在单个新列上排序实际SQL数据

时间:2016-06-20 14:32:58

标签: sql-server

我有几列数据:

A1, A2, A3... AN

每列都可以与其他列共享数据:

A1, A2, A3... AN
-------------------
P1, P4, P2, P3
P2, P3, P1, P3

我希望将单个列中的所有数据与以下分隔符一起订购:

A1, A2, A3... AN, ORDERED_DATA
---------------------------------
P1, P4, P2, P3, P1 | P2 | P3 | P4
P2, P3, P1, P3, P1 | P2 | P3 | P3

我需要一个SELECT查询。我不知道如何在concat之前订购。感谢。

3 个答案:

答案 0 :(得分:1)

你可以使用FOR XML连接值

来做这样的事情
SELECT  A1, A2, A3, A4, 
        STUFF(ca.data, 1, 3, '') AS Ordered_Data 
FROM    myTable
        OUTER APPLY (SELECT ' | ' + t.v
                     FROM ( VALUES(A1), (A2), (A3), (A4) ) t(v)
                     ORDER BY t.v
                     FOR XML PATH('')
                    ) ca(data)

如果您有空值,则可能需要在外部应用查询中使用WHERE t.v IS NOT NULL

答案 1 :(得分:0)

Declare @Table table (id int,A1 varchar(10),A2 varchar(10),A3 varchar(10),A4 varchar(10))
Insert Into @Table values 
(1,'P1','P4','P2','P3'),
(2,'P2','P3','P1','P3')

;with cteNorm as (
    Select id,Val = A1 From @Table
    Union All
    Select id,Val = A2 From @Table
    Union All
    Select id,Val = A3 From @Table
    Union All
    Select id,Val = A4 From @Table
)
Select id, Ordered = STUFF((
    SELECT ' | ' + val FROM cteNorm
    WHERE id = x.id
    Order by id,Val
    FOR XML PATH(''), TYPE).value('.[1]', 'nvarchar(max)'), 1, 2, '')
FROM cteNorm AS x
GROUP BY id

返回

id  Ordered
1   P1 | P2 | P3 | P4
2   P1 | P2 | P3 | P3

答案 2 :(得分:0)

使用UNPIVOTSTUFF / FOR XML的其他答案之外的其他方法:

SELECT  t.ID,
        t.A1,
        t.A2,
        t.A3,
        t.A4,
        STUFF((
               SELECT   ' | ' + unpvt.Val
               FROM     @table
               UNPIVOT ( Val FOR Col IN (A1, A2, A3, A4) ) unpvt
               WHERE    unpvt.ID = t.ID
               ORDER BY unpvt.Val
               FOR XML PATH('')
              ), 1, 3, '') AS ORDERED_DATA
FROM    @table AS t;

Working example

ID  A1  A2  A3  A4  ORDERED_DATA
1   P1  P4  P2  P3  P1 | P2 | P3 | P4
2   P2  P3  P1  P3  P1 | P2 | P3 | P3