在 SQL 中将行更改为列
Posted
技术标签:
【中文标题】在 SQL 中将行更改为列【英文标题】:Changing Rows to Column in SQL 【发布时间】:2018-10-19 05:34:52 【问题描述】:我有以下数据:
CREATE TABLE TimeLog (
[User] NVARCHAR(6),
[Event] NVARCHAR(3),
[Time] DATETIME
);
INSERT INTO TimeLog VALUES
(N'Jibran',N'IN','2015-04-15 00:31:00'),
(N'Jibran',N'IN','2015-04-16 20:10:00'),
(N'Jibran',N'IN','2015-04-21 14:59:00'),
(N'Jibran',N'OUT','2015-04-22 01:01:00'),
(N'Jibran',N'IN','2015-04-22 10:46:00'),
(N'Jibran',N'OUT','2015-04-23 00:58:00'),
(N'Jibran',N'IN','2015-04-23 14:50:00'),
(N'Jibran',N'OUT','2015-04-24 01:37:00')
我希望每个事件(对于每个 IN/OUT)都有一个以用户和时间为行的新列。
【问题讨论】:
提供您的预期输出 Convert Rows to columns using 'Pivot' in SQL Server的可能重复 【参考方案1】:在 case 中使用聚合函数
select user, max(case when Event='IN' then DATETIME end) as IN_time,
max(case when Event='OUT' then DATETIME end) as Out_time from t
group by user
【讨论】:
【参考方案2】:我假设您对每个用户都有连续的 IN
和 OUT
事件,按日期正确排序(与您的示例数据完全不同)。
您可以使用ROW_NUMBER
将IN
和OUT
事件成对分组,如下所示:
SELECT ROW_NUMBER() OVER (PARTITION BY [User] ORDER BY [Time]) + ROW_NUMBER() OVER (PARTITION BY [User] ORDER BY [Time]) % 2 AS [PairID]
,*
FROM [dbo].[TimeLog];
然后PIVOT
得到如下结果:
SELECT [User]
,[IN]
,[OUT]
FROM
(
SELECT ROW_NUMBER() OVER (PARTITION BY [User] ORDER BY [Time]) + ROW_NUMBER() OVER (PARTITION BY [User] ORDER BY [Time]) % 2 AS [PairID]
,*
FROM [dbo].[TimeLog]
) DS
PIVOT
(
MAX([Time]) FOR [Event] IN ([IN], [OUT])
) PVT
ORDER BY [PairID];
请注意,我已将您的 IN
事件之一更改为 OUT
以清理数据。如果这在您的实际示例中不正确,我想您仍然可以使用上面的逻辑。例如,对于您的示例数据,最大的 IN
事件是 get 并且它没有 OUT
事件:
您可以使用代码,将 MAX
更改为 MIN
或使用您的业务逻辑扩展它。
【讨论】:
以上是关于在 SQL 中将行更改为列的主要内容,如果未能解决你的问题,请参考以下文章