简体   繁体   English

MSSQL使用双列将2行合并为1

[英]MSSQL Merge 2 rows into 1 with double columns

I'm probably not searching correctly but cannot find this. 我可能没有正确搜索,但找不到这个。 I want to merge data from 2 rows into 1 row with double the columns. 我想将2行中的数据合并为1行,其中包含两列。 Selecting the one with the latest timestamp first. 首先选择具有最新时间戳的那个。 Then, if there are more than 2 row results, only take the first 2 rows. 然后,如果有超过2行结果,则只取前2行。 Example data and desired results below 示例数据和下面的期望结果

Source: 资源:

ID  Height  Color   Type    TimeStamp
1   6       Green   Plant   2017-09-23
1   24      Red     Tree    2017-09-15
1   33      Pink    Shrub   2016-05-14
2   12      Blue    Car     2017-03-21
2   88      Pink    Truck   2017-11-22

Desired Result: 期望的结果:

ID  Height1 Color1  Type1   Height2 Color2  Type2
1   6       Green   Plant   24      Red     Tree
2   88      Pink    Truck   12      Blue    Car

Been stumbling over this for a few days now. 现在已经磕磕绊绊几天了。 Help!!! 救命!!!

The way with OUTER APPLY: 使用OUTER APPLY的方式:

SELECT TOP 1 WITH TIES  y.ID,
                        y.Height as Height1,
                        y.Color as Color1,
                        y.[Type] as [Type1],
                        t.Height2,
                        t.Color2,
                        t.[Type2]
FROM YourTabel y
OUTER APPLY (
    SELECT TOP 1    Height as Height2,
                    Color as Color2,
                    [Type] as [Type2]
    FROM YourTabel 
    WHERE ID = y.ID AND [TimeStamp] < y.[TimeStamp]
    ORDER BY [TimeStamp] DESC
) as t
ORDER BY ROW_NUMBER() OVER (PARTITION BY y.ID ORDER BY y.[TimeStamp] DESC)

Output: 输出:

ID  Height1 Color1  Type1   Height2 Color2  Type2
1   6       Green   Plant   24      Red     Tree
2   88      Pink    Truck   12      Blue    Car

For SQL Server 2012 and upper you can use LAG : 对于SQL Server 2012及更高版本,您可以使用LAG

SELECT TOP 1 WITH TIES  y.ID,
                        y.Height as Height1,
                        y.Color as Color1,
                        y.[Type] as [Type1],
                        LAG(y.Height) OVER (PARTITION BY y.ID ORDER BY y.[TimeStamp] ASC) Height2,
                        LAG(y.Color) OVER (PARTITION BY y.ID ORDER BY y.[TimeStamp] ASC) Color2,
                        LAG(y.[Type]) OVER (PARTITION BY y.ID ORDER BY y.[TimeStamp] ASC) [Type2]
FROM YourTabel y
ORDER BY ROW_NUMBER() OVER (PARTITION BY y.ID ORDER BY y.[TimeStamp] DESC)

Try this (Assuming your table name is t1) 试试这个(假设你的表名是t1)

;WITH CTE
AS
(
   SELECT
  RN = ROW_NUMBER() OVER(partition by id ORDER BY TimeStamp desc,ID),    
  *
  FROM T1
)
SELECT
ID = ROW_NUMBER() OVER(ORDER BY C1.ID), 
C1.HEIGHT AS "HEIGHT1",
C1.COLOR Color1,  
C1.TYPE  Type1,   
C2.HEIGHT Height2, 
C2.COLOR Color2,  
C2.TYPE Type2
FROM CTE C1
  LEFT JOIN CTE C2
    ON C1.RN%2 = 1
      AND C2.RN%2 = 0
    WHERE C1.RN = C2.RN-1
      and c1.rn <3
      and c1.id = c2.id

Check the DEMO here 在这里查看演示

Play around with this: 玩弄这个:

DECLARE @DataSource TABLE
(
    [ID] INT
   ,[Height] INT
   ,[Color] VARCHAR(12)
   ,[Type] VARCHAR(12)
   ,[TimeStamp] DATETIME2
);

INSERT INTO @DataSource ([ID], [Height], [Color], [Type], [TimeStamp])
VALUES ('1', '6', 'Green', 'Plant', '2017-09-23')
      ,('1', '24', 'Red', 'Tree', ' 2017-09-15')
      ,('1', '33', 'Pink', 'Shrub', '2016-05-14')
      ,('1', '33', 'Pink', 'Shrub 1', '2016-05-13')
      ,('1', '33', 'Pink', 'Shrub 2', '2016-05-12')
      ,('1', '33', 'Pink', 'Shrub 3', '2016-05-11')
      ,('2', '12', 'Blue', 'Car', '  2017-03-21')
      ,('2', '88', 'Pink', 'Truck', '2017-11-22')
      ,('3', '12', 'test', 'test 2', '2017-11-22');

SELECT [ID]
      ,MAX(CASE WHEN [RowID] = 1 THEN [Height] ELSE NULL END) AS [Height1]
      ,MAX(CASE WHEN [RowID] = 1 THEN [Color] ELSE NULL END) AS [Color1]
      ,MAX(CASE WHEN [RowID] = 1 THEN [Type] ELSE NULL END) AS [Type1]
      ,MAX(CASE WHEN [RowID] = 2 THEN [Height] ELSE NULL END) AS [Height2]
      ,MAX(CASE WHEN [RowID] = 2 THEN [Color] ELSE NULL END) AS [Color2]
      ,MAX(CASE WHEN [RowID] = 2 THEN [Type] ELSE NULL END) AS [Type2]
FROM
(
    SELECT TOP (4) WITH TIES *
          ,ROW_NUMBER() OVER (PARTITION BY [ID] ORDER BY [TimeStamp] DESC) AS [RowID]
    FROM @DataSource
    ORDER BY [RowID]
) DS
GROUP BY [ID];

在此输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM