连接成对的SQL Server行

时间:2015-03-02 05:43:16

标签: sql-server

我有下表,已排序。

ID    Value     Amount
1       A        10.00
2       B         4.25 
3       C         2.01
4       D         5.00 

如何只连接连续的行对并将其转换为:

ID    Col1      Col2 
1,2    A,B     10.00,4.25 
3,4    C,D     2.01,5.00

我不想使用用户定义的表或临时表。我愿意使用 但是,SQL Server 2012和2014中提供了窗口函数。

3 个答案:

答案 0 :(得分:1)

我查看了其他解决方案并认为它有点过分,所以我重复使用了一些并排除或重写了不必要的部分。这应该会带来更好的性能。

;WITH cte (rn, id, Value, Amount)
AS
(
    SELECT ROW_NUMBER() OVER(ORDER BY id), id, Value, Amount
    FROM yourtable
)
SELECT 
    ( SELECT CAST(T.id AS VARCHAR(10)) + ','+ CAST(T1.id AS VARCHAR(10))
      FROM cte AS T1
      WHERE T1.rn = T.rn + 1) ID,
    ( SELECT CAST(T.value AS VARCHAR(10)) + ','+ CAST(T1.value AS VARCHAR(10))
      FROM cte AS T1
      WHERE T1.rn = T.rn + 1) COL1,
    ( SELECT CAST(T.Amount AS VARCHAR(10)) + ','+ CAST(T1.Amount AS VARCHAR(10))
      FROM cte AS T1
      WHERE T1.rn = T.rn + 1) COL2
FROM cte AS T
WHERE rn % 2 = 1

答案 1 :(得分:0)

试试这个,如果它不能与其他样本数据一起使用,请告诉我,

Declare @t table(ID varchar(50), Value varchar(50), Amount float)
insert into @t values(1,'A',10.00),(2,'B', 4.25),(3,'C',2.01)
,(4,'D',5.00 )
--Get the maxid
declare @MaxID int=(Select max(id) from @t)

;WITh CTE AS
(
 SELECT ID,
STUFF((select ','+ id from @t where id IN(1,2) for xml path('')),1,1,'') [id1]
,STUFF((select ','+ Value from @t where id IN(1,2) for xml path('')),1,1,'') [Value]
,STUFF((select ','+ cast(Amount as varchar) from @t where id IN(1,2) for xml path('')),1,1,'') [Amount]
,1 RN
FROM @T a WHERE ID=1
UNION ALL
SELECT B.ID,
STUFF((select ','+ id from @t where id IN(RN+2,RN+3) for xml path('')),1,1,'') 
,STUFF((select ','+ Value from @t where id IN(RN+2,RN+3) for xml path('')),1,1,'')
,STUFF((select ','+ cast(Amount as varchar) from @t where id IN(RN+2,RN+3) for xml path('')),1,1,'') 
, RN+2
FROM cte a 
CROSS APPLY(SELECT * FROM @T WHERE ID=RN+2 AND ID<=@MaxID) B 


)

SELECT ID1,Value,Amount FROM CTE

答案 2 :(得分:0)

这很好用..我们只使用row_number为每对生成唯一ID,并在这些ID上使用FOR XML PATH连接:

DECLARE @Test TABLE
(
     ID VARCHAR(50)
    , Value VARCHAR(50)
    , Amount FLOAT
);

INSERT INTO @Test
    (ID, Value, Amount)
VALUES 
      (1, 'A', 10.00)
      , (2, 'B', 4.25)
      , (3, 'C', 2.01)
      , (4, 'D', 5.00);

;WITH cte (rn, id, Value, Amount)
AS
(
    SELECT (ROW_NUMBER() OVER(ORDER BY id) + 1) / 2, id, Value, Amount
    FROM @Test
)
SELECT DISTINCT
    STUFF((SELECT ',' + CAST(T1.id AS VARCHAR(10))
            FROM cte AS T1
            WHERE T1.rn = T.rn
            ORDER BY T1.id
            FOR XML PATH('')), 1, 1, '') AS ID
    , STUFF((SELECT ',' + CAST(T2.Value AS VARCHAR(10))
            FROM cte AS T2
            WHERE T2.rn = T.rn
            ORDER BY T2.id
            FOR XML PATH('')), 1, 1, '') AS Col1
    , STUFF((SELECT ',' + CAST(T3.Amount AS VARCHAR(10))
            FROM cte AS T3
            WHERE T3.rn = T.rn
            ORDER BY T3.id
            FOR XML PATH('')), 1, 1, '') AS Col2
FROM cte AS T

<强>输出:

ID  Col1    Col2
-------------------
1,2 A,B     10,4.25
3,4 C,D     2.01,5