[英]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
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.