Объединение нескольких таблиц с Group_Concat, где некоторые записи существуют не во всех таблицах
Я пытаюсь выполнить довольно сложный (для меня) запрос, который будет извлекать поле "Описание" из главной таблицы, а затем добавлять к нему заголовки и значения из соответствующих справочных таблиц. Не все записи имеют записи в справочных таблицах. По мере продвижения я буду ставить дальнейшие вопросы как последующие вопросы, но для начала моя проблема заключается в том, что отображаются только те записи со значениями во всех таблицах.
- (ноль)
- Это запись 2 текста
Цвет:
красный
Фрукты:
яблоко - (ноль)
Если я использую Concat_WS, я получаю все записи, но мой "ярлык" в concat исчезает:
- Это запись 1 текста
синий - Это запись 2 текста
красный
яблоко - Это запись 3 текста
виноград
Итак, мой первый шаг - получить все описания записей, независимо от того, в скольких таблицах они существуют, и отобразить имена / метки.
2 ответа
Похоже, вам нужно COALESCE
:
Select J.id,
Concat(J.Description,
COALESCE(Concat('<b>Color</b>:<br>',
group_concat(F.Name SEPARATOR '<br>')),''),
'<br>',
COALESCE(Concat('<b>Fruit</b>:<br>',
group_concat(F2.Name SEPARATOR '<br>')),'')
) AS output
from Main J
Left Join LUT_1 L On J.ID=L.MainID
Left Join LUT_Names_1 F On F.ID=L.LUT_NAME_ID
Left Join LUT_2 L2 On J.ID=L2.MainID
Left Join LUT_Names_2 F2 On F2.ID=L2.LUT_NAME_ID
Group by J.ID;
РЕДАКТИРОВАТЬ:
Как всегда для MySQL, сам запрос основан на расширении MySQL. Если вы установите его ONLY_FULL_GROUP_BY
(по умолчанию для MySQL 5.7.5 и выше):
SET sql_mode=ONLY_FULL_GROUP_BY;
-- query will return error
J.Description'нет в GROUP BY
Чтобы исправить это, вам нужно использовать функцию агрегирования в этом столбце, например: MAX:
SET sql_mode=ONLY_FULL_GROUP_BY;
Select J.id,
Concat(MAX(J.Description),
COALESCE(Concat('<b>Color</b>:<br>',
group_concat(F.Name SEPARATOR '<br>')),''),
'<br>',
COALESCE(Concat('<b>Fruit</b>:<br>',
group_concat(F2.Name SEPARATOR '<br>')),'')
)
from Main J
Left Join LUT_1 L On J.ID=L.MainID
Left Join LUT_Names_1 F On F.ID=L.LUT_NAME_ID
Left Join LUT_2 L2 On J.ID=L2.MainID
Left Join LUT_Names_2 F2 On F2.ID=L2.LUT_NAME_ID
Group by J.ID;
Я думаю concat_ws()
может быть, скинуть то, что вы хотите сделать.
Следующее создает две метки, даже когда нет значений:
Select J.id,
Concat(J.Description,
'<br><br>',
'<b>Color</b>:<br>',
coalesce(group_concat(F.Name SEPARATOR '<br>'), ''),
'<br>',
'<b>Fruit</b>:<br>',
coalesce(group_concat(F2.Name SEPARATOR '<br>'), '')
)
from Main J Left Join
LUT_1 L
On J.ID = L.MainID Left Join
LUT_Names_1 F
On F.ID = L.LUT_NAME_ID Left Join
LUT_2 L2
On J.ID = L2.MainID Left Join
LUT_Names_2 F2
On F2.ID = L2.LUT_NAME_ID
Group by J.ID, J.Description;
Вот SQL Fiddle.
Кроме того, если у вас есть несколько фруктов или цветов, вы получите дубликаты. По этой причине вы хотите distinct
ключевое слово (или предварительно агрегировать по каждому измерению). Таким образом, рабочий SQL больше похож на это:
Select J.id,
Concat(J.Description,
'<br><br>',
'<b>Color</b>:<br>',
coalesce(group_concat(distinct F.Name SEPARATOR '<br>'), ''),
'<br>',
'<b>Fruit</b>:<br>',
coalesce(group_concat(distinct F2.Name SEPARATOR '<br>'), '')
)
from Main J Left Join
LUT_1 L
On J.ID = L.MainID Left Join
LUT_Names_1 F
On F.ID = L.LUT_NAME_ID Left Join
LUT_2 L2
On J.ID = L2.MainID Left Join
LUT_Names_2 F2
On F2.ID = L2.LUT_NAME_ID
Group by J.ID, J.Description
Вот SQL Fiddle, который иллюстрирует этот момент. Просто удалите distinct
и увидеть разницу в результатах.