MS SQL Server 2008中如何用LEFT OUTER JOIN返回逗号分隔的订单行列表?
在SQL Server 2008中实现订单与拼接订单行的查询
在SQL Server 2008里,我们没法直接用SQL Server 2017及以后版本才有的STRING_AGG函数,不过可以借助FOR XML PATH('')这个经典方案来实现你要的字符串聚合需求。下面是具体的实现步骤:
假设表结构
先明确一下我们用到的表结构(如果你的表字段或名称不同,直接替换即可):
- Orders表:订单主表,包含
order_id(主键,关联订单行)、custno、name、email、phone字段 - OrderLines表:订单行表,包含
order_line_id、order_id(外键关联Orders)、item_no(商品编号)、item_name(商品名称)、price(商品价格)字段
实现SQL语句
SELECT o.custno, o.name, o.email, o.phone, -- 处理无订单行的情况,返回空字符串而非NULL ISNULL( STUFF( ( -- 拼接单条订单行的字段,用双引号包裹、逗号分隔;不同行用分号分隔 SELECT ';' + '"' + ol.item_no + '","' + REPLACE(ol.item_name, '"', '""') + '","' + CAST(ol.price AS VARCHAR(20)) + '"' FROM OrderLines ol WHERE ol.order_id = o.order_id FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)'), 1, 1, '' -- 移除开头多余的分号 ), '' ) AS [Order lines] FROM Orders o -- 用LEFT OUTER JOIN确保所有订单都被返回,哪怕没有对应订单行 LEFT OUTER JOIN OrderLines ol ON o.order_id = ol.order_id -- 按订单唯一标识分组,保证每个订单只返回一行结果 GROUP BY o.order_id, o.custno, o.name, o.email, o.phone
关键部分说明
FOR XML PATH(''):它会把每个订单行的拼接结果合并成一个XML字符串,加上TYPE参数是为了避免特殊字符(比如&、<)被自动转义,保证输出内容的准确性。.value('.', 'NVARCHAR(MAX)'):把生成的XML类型数据转换成普通字符串,方便后续处理。STUFF函数:用来去掉拼接结果开头多余的分号(因为第一条订单行前面也会被加上分号,所以从第1位开始删除1个字符)。ISNULL函数:如果某个订单没有对应的订单行,聚合结果会是NULL,用这个函数把它转换成空字符串,让输出更整洁。REPLACE(ol.item_name, '"', '""'):如果商品名称里包含双引号,用这个逻辑转义处理,避免破坏整体的双引号包裹格式。
效果示例
执行上面的语句后,就能得到你想要的输出格式:
| Orders.custno | Orders.name | Orders.email | Orders.phone | Order lines |
|---|---|---|---|---|
| 123456 | Dave | dave@example.com | 1234567890 | "112233","Running shoes","495.00";"223344","Roller blades","699.00" |
内容的提问来源于stack exchange,提问作者Ploughansen
相关产品推荐
相关产品推荐

