我需要将数据从 SQL 数据库(某些组使用 SQL Server,某些组使用 Oracle 等)导出到 CSV,其中我需要字符串中连接表中的 id。
例如,我有一个班级表和一个学生表。对于班级,我需要 ID、姓名、部门、时间;对于学生,我需要班级中学生的 ID 字符串。结果将返回列:id、name、section、time、student_ids。 “student_ids”列应该是分隔字符串,例如:
'32,43,53,12,41'
行输出最终会类似于:
"1405,Computer Science,101,12-1:30,'32,43,53,12,41'"
每个班级的学生人数不一致,可能有1名学生,也可能有20名学生。我考虑过使用 SQL Server 的 while 循环来获取此数据,或者使用聚合键的临时表,但我想知道是否有任何方法使用标准 SQL 来完成此操作,以便脚本可以移植。
注意:我知道输出格式并不理想,但唯一的其他选择是我们必须为每个班级/学生组合提取不同的记录,然后必须单独聚合 id。
不同的 RDBMS 有不同的方式来执行此类查询。
GROUP_CONCAT
聚合函数。
LIST
聚合函数。
如果您使用的是 SQL Server,那么在 sql-server-group-concat 下有一些已回答的问题。通常的方法是使用
FOR XML PATH
结构。一个很好的例子是:SQL 查询以逗号分隔符获取聚合结果以及 SQL Server 中的按列分组
在 Oracle 中有几种方法可以做到这一点,有一篇很好的文章这里。
如果是SQL Server,我倾向于这样做:
SELECT c.classID, c.other columns,
STUFF((SELECT ',' + convert(varchar,StudentID)
FROM StudentClass sc where c.ClassId = sc.ClassID
FOR XML PATH('')),1,1,'') as StudentIdList
from ClassTable c
这假设您有一个 ID 为
ClassTable
的 ClassId
,还有一个包含 StudentClass
和 StudentId
的 ClassId
链接表。
编辑:您必须有某种包含学生和班级信息的表格,以便将两者链接在一起。要么是一个链接表,要么如果每个学生只允许上一堂课,那么
ClassId
可能存储在学生表中。不管怎样,以上内容应该可以帮助你解决你的问题。
你的问题的答案是:不,它不能用标准 SQL 来完成。
这是因为您试图将多个值放入一个字段中,这违反了第一范式。
您可以使用非标准 sql 来完成此操作,但每个数据库的 sql 会有所不同。
但是,您也可以使用 SSRS 中的 tablix 来完成此操作(它可以使用相同的标准 SQL 来访问 Oracle 和 SQLServer 中的表)。
我们现在有 STRING_AGG 来帮忙解决这个问题...
CREATE TABLE #people
(id INT,person_name VARCHAR(50))
CREATE TABLE #hobbies
(id INT,hobby VARCHAR(50))
INSERT #people
VALUES (1,'fred'),(2,'Raj')
INSERT #hobbies
VALUES (1,'lying down'),(1,'standing up'),(2,'jumping'),(2,'chasing dogs')
SELECT person_name,STRING_AGG(hobby,',') AS hobby_csv
FROM #people p
JOIN #hobbies h
ON p.id=h.id
GROUP BY person_name
person_name hobby_csv
-------------------------------------------------- ----------------------
fred lying down,standing up
Raj jumping,chasing dogs
(2 rows affected)