多个 Table 与 Group_Concat 联接,其中某些记录不存在于所有表中

Multiple Table Joins with Group_Concat where some records don't exist in all tables

我正在尝试做一个相当复杂的(对我来说)查询,它将从 Main Table 中获取一个 Description 字段,然后将其附加到相关 Look-Up-Tables 中的标题和值。并非所有记录都在 Look-up 表中有记录。随着我的进行,我将提出更多问题作为后续问题,但首先我的问题是只有那些在所有表中都有值的记录才会显示。

http://sqlfiddle.com/#!9/09047/13

如果我使用 Concat_WS 我会得到所有记录,但我在 concat 中的 'label' 消失了:

http://sqlfiddle.com/#!9/09047/16

所以我的第一步是获取所有记录描述,无论它们存在多少 Look-up-Table 并显示 Names/Labels。

看来你需要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;

SQLFiddle Demo

编辑:

与 MySQL 一样,查询本身基于 MySQL 扩展。如果将其设置为 ONLY_FULL_GROUP_BY(MySQL 5.7.5 及更高版本的默认值):

SET sql_mode=ONLY_FULL_GROUP_BY;
-- query will return error

J.Description' isn't in 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;

Here 是 SQL Fiddle.

此外,如果您有多种水果或颜色,您将得到重复的。因此,您需要 distinct 关键字(或 pre-aggregate 每个维度)。所以工作 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

Here是一个SQLFiddle说明了这一点。只需删除 distinct 并查看结果的差异。