您的位置:首页 > 数据库

灵活运用 SQL Server 数据库的 FOR XML PATH

2012-03-12 13:50 459 查看

起因

今天欧阳冰提出一个报表需求,其核心部分可以简化为这样一张表格:

调度单号与调度单相关的多张作业单号
0010001/0002/0003
0020004
0030005/0006/0007/0008
从上述表格可以看出,如何把调度单的多行作业单明细的单号合并到同一行的一个字段中,并用斜杠 / 分隔,是这个需求的难点。

解决

于是到网上去搜索了一下,有这样一篇文章:灵活运用 SQL SERVER FOR XML PATH
其中介绍了 SQL Server 数据库的 FOR XML PATH 关键字的用法。

在一句 SELECT 语句的最后加上 FOR XML PATH,就可以把整个结果数据集变成一个 xml 字符串。大家可以自行尝试一下。
而如果使用 FOR XML PATH(''),则是去除所有 xml 节点标记,只剩下原原本本的数据。我们要的就是这个。

于是,我们可以写 SQL:

SELECT DH.DH_DISPATCH_NO DISPATCH_NO,
(
SELECT CLH.CLH_CARGO_LOAD_NO + '/'
FROM TM_DISPATCH_CARGO_LOAD_L DCLL, TM_CARGO_LOAD_H CLH
WHERE DH.BILLID = DCLL.BILLID AND DCLL.DCLL_CARGO_LOAD_HEADER_ID = CLH.BILLID
FOR XML PATH('')
) NOS
FROM TM_DISPATCH_H DH
GROUP BY DH.BILLID, DH.DH_DISPATCH_NO
;


这样就已经差不多了,但是多张作业单号这一列最后总是多个斜杠 /。

为了把最后这个斜杠去掉,我们还要使用一下 LEFT 函数。那么最终可以使用这样一句 SQL 来满足上述需求:

SELECT DISPATCH_NO, LEFT(NOS, LEN(NOS)-1) CARGO_LOAD_NOS
FROM
(
SELECT DH.DH_DISPATCH_NO DISPATCH_NO,
(
SELECT CLH.CLH_CARGO_LOAD_NO + '/'
FROM TM_DISPATCH_CARGO_LOAD_L DCLL, TM_CARGO_LOAD_H CLH
WHERE DH.BILLID = DCLL.BILLID AND DCLL.DCLL_CARGO_LOAD_HEADER_ID = CLH.BILLID
FOR XML PATH('')
) NOS
FROM TM_DISPATCH_H DH
GROUP BY DH.BILLID, DH.DH_DISPATCH_NO
) TMP
ORDER BY DISPATCH_NO
;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: