使用 MS SQL Server 2005,如何将详细记录合并到一个逗号分隔的列表中
Posted
技术标签:
【中文标题】使用 MS SQL Server 2005,如何将详细记录合并到一个逗号分隔的列表中【英文标题】:Using MS SQL Server 2005, how can I consolidate detail records into a single comma separated list 【发布时间】:2010-10-07 13:01:30 【问题描述】:背景:**我正在运行 **MS2005。我有一个 MASTER 表(ID,MDESC)和一个 DETAIL 表(MID,DID,DDESC),数据如下
1 MASTER_1
2 MASTER_2
1 L1 DETAIL_M1_L1
1 L2 DETAIL_M1_L2
1 L3 DETAIL_M1_L3
2 L1 DETAIL_M2_L1
2 L2 DETAIL_M2_L2
如果我用
加入表格SELECT M.*, D.DID FROM MASTER M INNER JOIN DETAIL D on M.ID = D.MID
我得到如下列表:
1 MASTER_1 L1
1 MASTER_1 L2
1 MASTER_1 L3
2 MASTER_2 L1
2 MASTER_2 L2
问题:有没有办法使用 MS SQL 选择语句将详细记录放入逗号分隔的列表中,如下所示:
1 MASTER_1 "L1, L2, L3"
2 MASTER_2 "L1, L2"
【问题讨论】:
【参考方案1】:你需要一个函数:-
CREATE FUNCTION [dbo].[FN_DETAIL_LIST]
(
@masterid int
)
RETURNS varchar(8000)
AS
BEGIN
DECLARE @dids varchar(8000)
SELECT @dids = COALESCE(@dids + ', ', '') + DID
FROM DETAIL
WHERE MID = @masterid
RETURN @dids
END
用法:-
SELECT MASTERID, [dbo].[FN_DETAIL_LIST](MASTERID) [DIDS]
FROM MASTER
【讨论】:
查看发布的没有功能的解决方案......非常漂亮 这突出了为什么在问题中指定版本是好的。 APPLY 是 SQL 2005 的东西。 SQL Server 的寿命往往很长,因此在没有版本信息的情况下,我会选择与 SQL 2000 兼容的答案。 是的,由于拥有 SQL Server 2000,这是我将使用的解决方案,谢谢【参考方案2】:感谢 Bill Karwin 链接中的概念,正是 CROSS APPLY 使它起作用
SELECT ID, DES, LEFT(DIDS, LEN(DIDS)-1) AS DIDS
FROM MASTER M1 INNER JOIN DETAIL D on M1.ID = D.MID
CROSS APPLY (
SELECT DID + ', '
FROM MASTER M2 INNER JOIN DETAIL D on M2.ID = D.MID
WHERE M1.ID = M2.ID
FOR XML PATH('')
) pre_trimmed (DIDS)
GROUP BY ID, DES, DIDS
结果:
ID DES DIDS
--- ---------- ---------------
1 MASTER_1 L1, L2, L3
2 MASTER_2 L1, L2
【讨论】:
我同意它非常巧妙,虽然对 XML 的依赖有点令人不安,但如果在不影响性能的情况下运行得足够好,这是一个很好的解决方案。【参考方案3】:coalesce 是你的朋友。
declare @CSL vachar(max)
set @CSL = NULL
select @CSL = coalesce(@CSL + ', ', '') + cast(DID as varchar(8))
from MASTER M INNER JOIN DETAIL D on M.ID = D.MID
select @CSL
这不适用于通用查询(即,适用于单个主记录)。
您可以将其放入一个函数中...但这可能无法为您提供所需/想要的性能。
【讨论】:
他可以将类似上面的内容包装到一个函数中,该函数将主表中的 id 作为输入,并返回逗号分隔的字符串。 不错,但在一行上返回所有内容,例如“L1、L2、L3、L1、L2”我需要按主行分组【参考方案4】:这就是 mysql 的 GROUP_CONCAT()
聚合函数的目的。不幸的是,在其他不支持该功能的 RDBMS 品牌中复制此功能并不容易。
见Simulating group_concat MySQL function in Microsoft SQL Server 2005?
【讨论】:
感谢您的链接,SQL Server 中添加了一些我以前从未注意到的 CROSS APPLY 新功能。【参考方案5】:我认为您需要一个函数才能在最新版本的 SQL Server 中正常工作:
http://sqljunkies.com/WebLog/amachanic/archive/2004/11/10/5065.aspx?Pending=true
【讨论】:
感谢我的想法,但请参阅发布的纯 SQL 解决方案以上是关于使用 MS SQL Server 2005,如何将详细记录合并到一个逗号分隔的列表中的主要内容,如果未能解决你的问题,请参考以下文章
如何在 MS Access 2007 或 MS SQL Server 2005 中通过 SQL 将字段转换为行
使用 MS Access 2003 连接到 SQL Server 2005
从 Ms Access Mdb 文件获取数据到 sql server 2005 的最佳方法
MS SQL Server 2005 中的 LIMIT 样式功能