我有2个表,一个有人员数据,另一个有志愿者查询代码:
Person Table
| ID | UID | First | Last | VolCode | VolYear
| 00 | 09123 | John | Doe | A01 | 2016
| 01 | 09123 | John | Doe | A02 | 2016
| 02 | 09123 | John | Doe | A03 | 2016
-
Vol Table
| ID | VolCode | Name |
| 00 | A01 | Something |
| 01 | A02 | Something |
| 02 | A03 | Something |
期望的结果:
Results
| p.UID | p.First | p.Last | v.VolCodes | v.volYear |
| 09123 | John | Does | A01,A02,A03 | 2016 |
在SQL中是否有办法创建一个包含连续的VolCode列表的列,例如所需的结果?
答案 0 :(得分:0)
取决于您的DBMS。
PostgreSQL 聚合函数称为array_agg
SELECT a, array_agg(b)
FROM (VALUES (1, 'abc'), (1, 'def'), (1, 'xyz')) t ( a, b )
GROUP BY a;
给出了
a | array_agg
---+---------------
1 | {abc,def,xyz}
MySQL / MariaDB
聚合函数称为GROUP_CONCAT
。
可能是这样的:
SELECT a, group_concat(b)
FROM (VALUES (1, 'abc'), (1, 'def'), (1, 'xyz')) t ( a, b )
GROUP BY a;
您的预期结果似乎只是使用了第一个表格。您确定不会引用person.volCode
引用vol.id
的外键引用吗?问题是如何将行汇总在一起 - 您是GROUP BY person.uid
吗?到person.year
?
您的示例的查询可能是(仅使用person
表):
SELECT uid, first, last, array_agg(volCode) AS "volCodes", volYear
FROM person
GROUP BY uid, first, last, volYear;
您应该知道,volCodes
列中没有原子值(不是第一范式),您无法轻松继续处理此列。在聚合之前,您有3行,您可以使用WHERE
子句轻松过滤。汇总后,过滤部分汇总值volCodes
要困难得多。此外,GROUP BY
字段上的索引可能会加快分组速度。我们仍然不知道应该聚合哪些值。我在这里假设所有4列(uid, first, last, volYear
) - 它可能会有所不同 - 这取决于你。
如果您只想GROUP BY uid
,则列first, last, volYear
是多值的。您也可以array_agg
像这样
SELECT uid,
array_agg(first),
array_agg(last),
array_agg(volCode) AS "volCodes",
array_agg(volYear)
FROM person
GROUP BY uid;
将携带相同的firstname
三次(因为您的示例表数据)。
或者你可以用
选择最小值或其他东西SELECT uid,
MIN(first), -- chooses the alphabetically ordered firstname
MIN(last),
array_agg(volCode) AS "volCodes",
MIN(volYear)
FROM person
GROUP BY uid;
这可能不是你想要的。