SQL:将连接表的 id 聚合为字符串

问题描述 投票:0回答:4

我需要将数据从 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。

sql join csv export
4个回答
2
投票

不同的 RDBMS 有不同的方式来执行此类查询。

如果您使用 MySQL,您应该看看

GROUP_CONCAT
聚合函数。

在 Firebird 中,您有

LIST
聚合函数。

如果您使用的是 SQL Server,那么在 下有一些已回答的问题。通常的方法是使用

FOR XML PATH
结构。一个很好的例子是:SQL 查询以逗号分隔符获取聚合结果以及 SQL Server 中的按列分组

在 Oracle 中有几种方法可以做到这一点,有一篇很好的文章这里


1
投票

如果是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
可能存储在学生表中。不管怎样,以上内容应该可以帮助你解决你的问题。


0
投票

你的问题的答案是:不,它不能用标准 SQL 来完成。

这是因为您试图将多个值放入一个字段中,这违反了第一范式。

您可以使用非标准 sql 来完成此操作,但每个数据库的 sql 会有所不同。

但是,您也可以使用 SSRS 中的 tablix 来完成此操作(它可以使用相同的标准 SQL 来访问 Oracle 和 SQLServer 中的表)。


0
投票

我们现在有 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)
© www.soinside.com 2019 - 2024. All rights reserved.