Фильтрация данных в левом соединении

#mysql #sql #join

#mysql #sql #Присоединиться

Вопрос:

Вот некоторые данные:

 record
-------------------------------------------------
| id      | name                                |
-------------------------------------------------
| 1       | Round Cookie                        |
| 2       | Square Cookie                       |
| 3       | Oval Cookie                         |
| 4       | Hexagon Cookie                      |
-------------------------------------------------

record_field_data
----------------------------------------------
| id      | record_id | data       | type_id |
----------------------------------------------
| 1       | 1         | White      | 1       |
| 2       | 1         | Round      | 2       |
| 3       | 2         | Green      | 1       |
| 4       | 2         | Square     | 2       |
| 5       | 3         | Blue       | 1       |
| 6       | 3         | Oval       | 2       |
| 7       | 4         | Hexagon    | 2       |
----------------------------------------------

record_type_field
-------------------------------------------------
| id      | data_type                           |
-------------------------------------------------
| 1       | Color                               |
| 2       | Shape                               |
-------------------------------------------------
 

Я пытаюсь получить список всех оставшихся записей, соединенных с record_field_data типа «Color». Это должно быть левое соединение, потому что может не быть record_field_data данного типа, и я все равно хочу запись, если это так.

Это запрос, который я придумал, но он возвращает левое соединение со ВСЕМИ record_field_data, а не только с конкретными, которые я хочу.

 SELECT record.id AS id, recordfield.data, recordtype.field_name
FROM record
LEFT JOIN record_field_data AS recordfield ON (record.id = recordfield.record_id)
LEFT JOIN record_type_field AS recordtype ON (recordfield.type_id = recordtype.id AND recordtype.data_type = 'Color');
 

Я мог бы сделать это с помощью подзапроса в СОЕДИНЕНИИ, но я не могу использовать подзапрос. Я должен перевести это в HQL, а подзапросы для объединений в HQL не поддерживаются.

Результат, который я ищу, — это записи, упорядоченные по параметру record_field_data, где record_type_field.data_type — это «Цвет». Обратите внимание, что «Шестиугольное печенье» не имеет определенного цвета, я не знаю, должно ли оно быть вверху или внизу в данный момент. Любой способ сработает.

     -------------------------------------------------
    | id      | name                                |
    -------------------------------------------------
    | 3       | Oval Cookie                         |
    | 2       | Square Cookie                       |
    | 1       | Round Cookie                        |
    | 4       | Hexagon Cookie                      |
    -------------------------------------------------
 

Комментарии:

1. Пожалуйста, отредактируйте свой вопрос и укажите результаты, которые вы ищете.

2. Добавлен желаемый результат.

Ответ №1:

 SELECT  r.id, r.name
FROM    record r
JOIN    record_type_field rf
ON      rf.data_type = 'Color'
LEFT JOIN
        record_type_data rd
ON      rd.record_id = r.id
        AND rd.type_id = rf.id
ORDER BY
        rd.data
 

Комментарии:

1. Рабочая демонстрация моя логика была неправильной 1 для вас

2. Это работает … к сожалению, я не думаю, что смогу сделать это и в HQL. 🙁

3. @Quassnoi: Проблема в том, что HQL не поддерживает директивы ON для объединений. Объединения предопределены моделью сущности, поэтому все, что я делаю, должно вписываться в эту структуру. Я попытался придумать запрос HQL, похожий на этот запрос, но мне не очень повезло.

Ответ №2:

Вы пробовали использовать предложение SQL ‘IN’.

 select record.id as id, recordfield.data, recordtype.field_name
from record
left join record_field_data recordfield ON record.id = recordfield.record_id
WHERE id IN (SELECT id FROM record_type_field where data_type='Color');
 

Предложение IN позволяет вам указать условие списка. Таким образом, подзапрос получает все идентификаторы, где тип «Color», и затем вы выполняете объединение и выбираете все записи из этого объединения, которые имеют идентификатор в списке идентификаторов, соответствующих типу «Color».

Комментарии:

1. Предложение where отфильтрует записи, которым не присвоен цвет.

Ответ №3:

Вы должны изменить второе соединение на a INNER JOIN .

Если вы используете два LEFT JOIN s, вы выбираете все записи из record И из record_field_data .

Комментарии:

1. ...This needs to be a left join because there may not be record_field_data of a given type...