[英]Using GROUP_CONCAT
我有三张桌子。 TB_Main是实体表。 TB_BoardMembers是一个人的表。 TB_BoardMembersLINK是一个桥接表,它通过ID引用其他两个表,并且还具有某人在实体董事会上的开始和结束日期。 这些日期通常不完整。
我被要求导出一份CSV格式的报告作为报告的一部分,每个实体每年一行,其中我列出了当年的董事会成员列表,他们的职业在换行符分隔的单个字段中。
我不需要在结果中使用bml.Entity,但将其添加到调试中。 我在期望85的位置得到了一行。在有和没有GROUP BY的情况下进行了尝试,结果相同的事实表明我在滥用GROUP_CONCAT。 我应该如何构造它以获得他们想要的结果?
SELECT
GROUP_CONCAT(
DISTINCT CONCAT(bm.First, ' ', bm.Last,
IF (bm.Occupation != '', ' - ', ''),
bm.Occupation) SEPARATOR "\n") as Board,
bml.Entity
FROM
TB_Main arfe,
TB_BoardMembers bm,
TB_BoardMembersLINK bml
WHERE YEAR(bml.start) <= 2011
AND (YEAR(bml.end) >= 2011 OR bml.end IS NULL)
AND bml.start > 0
AND bml.Entity = arfe.ID
GROUP BY bml.Entity
ORDER BY Board
此查询存在一些问题。 主要问题似乎是您缺少将董事会成员链接到链接表的条件,因此您进行了交叉联接,即您将返回每个宽带成员,无论其开始/结束日期如何,并假设您有85行如果符合条件,您实际上将退回每个董事会成员85次。 这突出了一个很好的理由,即将您正在使用的ANSI 89隐式连接切换为ANSI 92显式连接语法。 本文重点介绍了进行切换的一些很好的理由。
因此,您的查询将变为(我不得不猜测您的字段名称):
SELECT *
FROM TB_Main arfe
INNER JOIN TB_BoardMembersLINK bml
ON bml.Entity = arfe.ID
INNER JOIN TB_BoardMembers bm
ON bm.ID = bml.BoardMemberID
关于您的查询,我注意到的第二件事是,在where子句中使用函数根本不是很有效,因此:
WHERE YEAR(bml.start) <= 2011
AND (YEAR(bml.end) >= 2011 OR bml.end IS NULL)
您对每一行都使用了两次YEAR
函数,并消除了在bml.Start
或bml.End
(如果存在)上使用索引的任何可能的机会。 Aaron Bertrand再次写了一篇不错的文章,着重介绍了查询日期范围时的良好做法,它的目标是SQL-Server,但是原理仍然相同,因此where子句将变为:
WHERE bml.Start <= '20110101'
AND (bml.End >= '20110101' OR bml.End IS NULL)
AND bml.start > 0
您的最终查询应为:
SELECT bml.Entity,
GROUP_CONCAT(DISTINCT CONCAT(bm.First, ' ', bm.Last,
IF (bm.Occupation != '', ' - ', ''), bm.Occupation)
SEPARATOR "\n") as Board
FROM TB_Main arfe
INNER JOIN TB_BoardMembersLINK bml
ON bml.Entity = arfe.ID
INNER JOIN TB_BoardMembers bm
ON bm.ID = bml.BoardMemberID
WHERE bml.Start <= '20110101'
AND (bml.End >= '20110101' OR bml.End IS NULL)
AND bml.start > 0
GROUP BY bml.Entity
ORDER BY Board;
如果您阅读Group_Concat
“此函数返回一个字符串结果,其中包含来自组的串联的非NULL值。”
在这种情况下,该组似乎只是一个组,因为您说只有一个实体? 我不确定您的描述是否属实。 为什么不同时按名字,姓氏和职业分组,这可能会给您所有成员。
我也不确定您的联接,没有真实数据就很难解释该部分,因为每个联接都可以正确地处理某些数据集,即使这不是编写查询的最佳方式
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.