多个 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
- (空)
- 这是记录 2 文本
颜色:
红色
水果:
苹果
- (空)
如果我使用 Concat_WS 我会得到所有记录,但我在 concat 中的 'label' 消失了:
http://sqlfiddle.com/#!9/09047/16
- 这是记录 1 文本
蓝色
- 这是记录 2 文字
红色
苹果
- 这是记录 3 文本
葡萄
所以我的第一步是获取所有记录描述,无论它们存在多少 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;
编辑:
与 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
并查看结果的差异。
我正在尝试做一个相当复杂的(对我来说)查询,它将从 Main Table 中获取一个 Description 字段,然后将其附加到相关 Look-Up-Tables 中的标题和值。并非所有记录都在 Look-up 表中有记录。随着我的进行,我将提出更多问题作为后续问题,但首先我的问题是只有那些在所有表中都有值的记录才会显示。
http://sqlfiddle.com/#!9/09047/13
- (空)
- 这是记录 2 文本
颜色:
红色
水果:
苹果 - (空)
如果我使用 Concat_WS 我会得到所有记录,但我在 concat 中的 'label' 消失了:
http://sqlfiddle.com/#!9/09047/16
- 这是记录 1 文本
蓝色 - 这是记录 2 文字
红色
苹果 - 这是记录 3 文本
葡萄
所以我的第一步是获取所有记录描述,无论它们存在多少 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;
编辑:
与 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
并查看结果的差异。