Sql 基于唯一标识符列合并单独的行

Sql 基于唯一标识符列合并单独的行,sql,Sql,我有两个表,一个带有个人数据,另一个带有志愿者查找代码: 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 - 预期结果: Results | p.UID

我有两个表,一个带有个人数据,另一个带有志愿者查找代码:

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
-

预期结果:

Results
| p.UID | p.First | p.Last | v.VolCodes  | v.volYear   |
| 09123 | John    | Does   | A01,A02,A03 | 2016        |
在SQL中是否有一种方法可以创建一个列,其中包含一个级联的volcode列表,如在所需的结果中?

取决于您的DBMS

PostgreSQL调用聚合函数

 a |   array_agg   
---+---------------
 1 | {abc,def,xyz}
MySQL/MariaDB 调用聚合函数。 可能是这样的:

SELECT a, group_concat(b) 
FROM (VALUES (1, 'abc'), (1, 'def'), (1, 'xyz')) t ( a, b ) 
GROUP BY a;
您的预期结果似乎只使用了第一个表。您确定没有来自
person.volCode
引用
vol.id
的外键引用吗?问题是如何将行聚合在一起-是否按person.uid对行进行分组?按
人年
? 示例的查询可以是(仅使用
person
表):

您应该知道,
volCodes
列中没有原子值(不是第一个标准形式),您无法轻松继续处理此列。在聚合之前,您有3行,可以使用
WHERE
子句轻松筛选这些行。聚合后,要对聚合值的某些部分进行过滤要困难得多
volCodes
。此外,
groupby
字段上的索引可能会加快分组速度。我们仍然不知道应该在哪些值上进行聚合。我只是假设这里的所有4列(
uid、first、last、volYear
)可能会有所不同,这取决于您

如果只想按uid对
进行分组,则列
first、last、volYear
是多值的。您也可以像这样
array\u 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;

但这可能不是您真正想要的。

您使用的是哪种?博士后?Oracle?大多数SQL系统不容易支持字符串聚合。如果可能的话,我会强烈地考虑在显示层(报告、表单、网页等)中做那个逻辑。
SELECT uid, first, last, array_agg(volCode) AS "volCodes", volYear 
FROM person  
GROUP BY uid, first, last, volYear;
SELECT uid, 
       array_agg(first), 
       array_agg(last), 
       array_agg(volCode) AS "volCodes", 
       array_agg(volYear) 
FROM person  
GROUP BY uid;
SELECT uid, 
       MIN(first), -- chooses the alphabetically ordered firstname
       MIN(last), 
       array_agg(volCode) AS "volCodes", 
       MIN(volYear) 
FROM person  
GROUP BY uid;