[英]SQL SELECT concatenate distinct column values in comma separated value
我有一個包含訂單詳細信息的表。 該表的每一行都是訂單的一個項目,每一行都有一個名為服務的列,這是一個以逗號分隔的與該項目相關的服務列表。
ID | order_id | 服務 |
---|---|---|
1個 | 1個 | 123 |
2個 | 1個 | 123,456 |
3個 | 2個 | 456,789 |
4個 | 2個 | 123 |
5個 | 2個 | 789,456 |
我達到的是連續的結果
訂單_服務 |
---|
123,123,456 |
通過此查詢獲得
SELECT STUFF(
(SELECT DISTINCT ',' + services
FROM order_detail
WHERE order_id = 1
FOR XML PATH ('')), 1, 1, '') AS Order_Services
我想從單個 order_id 獲得一系列串聯服務的結果集,但我也想刪除重復項。 STUFF 中的 distinc 非常無用,因為它只刪除相等的列(例如,不刪除值“123,456”和“456,123”之一,因為它們不是同一件事)
我的預期結果是
對於order_id=1
訂單_服務 |
---|
123,456 |
對於order_id=2
訂單_服務 |
---|
123,456,789 |
有沒有一種簡單的方法可以實現這一目標?
我的 SQL 版本是:
Microsoft SQL Server 2005 - 9.00.4035.00 (X64) Nov 24 2008 16:17:31 版權所有 (c) 1988-2005 Microsoft Corporation Enterprise Edition(64 位)Windows NT 6.1(Build 7601:Service Pack 1)
或 SQL 代碼復制示例
CREATE TABLE order_detail ( ID INT IDENTITY(1,1) PRIMARY KEY, order_id INT, services varchar(100));
INSERT INTO order_detail (order_id,services) VALUES (1, '123' ), (1, '123,456' ), (2, '456,789' ),(2,'123'),(2,'789,456')
SELECT
STUFF(
(SELECT DISTINCT ',' + services
FROM order_detail
WHERE order_id = 1
FOR XML PATH (''))
, 1, 1, '') AS Order_Services
您可以在 SQL Server 2005 中使用拆分 function 執行此操作,例如來自 這篇文章:
CREATE FUNCTION dbo.SplitStrings_XML
(
@List nvarchar(max),
@Delimiter nvarchar(255)
)
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN
(
SELECT Item = y.i.value(N'(./text())[1]', N'nvarchar(4000)')
FROM
(
SELECT x = CONVERT(XML, '<i>'
+ REPLACE(@List, @Delimiter, '</i><i>')
+ '</i>').query('.')
) AS a CROSS APPLY x.nodes('i') AS y(i)
);
GO
然后你可以說:
;WITH cte AS
(
SELECT d.order_id, f.Item
FROM dbo.order_detail AS d
CROSS APPLY dbo.SplitStrings_XML(d.services, ',') AS f
GROUP BY d.order_id, f.Item
),
sub AS
(
SELECT cte.order_id, Order_Services = STUFF(
(SELECT ',' + x.Item
FROM cte AS x
WHERE x.order_id = cte.order_id
FOR XML PATH(''),
TYPE).value(N'./text()[1]', N'varchar(max)'),
1, 1, '')
FROM cte
)
SELECT order_id, Order_Services
FROM sub
GROUP BY order_id, Order_Services;
Output:
order_id | 訂單_服務 |
---|---|
1個 | 123,456 |
2個 | 123,456,789 |
如果您認為,“哇,這真是一個丑陋而復雜的查詢。” 沒錯,SQL 服務器的現代版本支持更優雅的方法,並且正確規范化的數據首先不需要任何版本的任何此類雜技。
SQL Server 2017+ 中的方法不需要自定義 function 或混亂的 XML 處理任一方向:
;WITH cte AS
(
SELECT d.order_id, s.value
FROM dbo.order_detail AS d
CROSS APPLY STRING_SPLIT(d.services, ',') AS s
GROUP BY d.order_id, s.value
)
SELECT order_id, STRING_AGG(value, ',')
FROM cte
GROUP BY order_id;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.