在 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】:

我假设您对每个用户都有连续的 INOUT 事件,按日期正确排序(与您的示例数据完全不同)。

您可以使用ROW_NUMBERINOUT 事件成对分组,如下所示:

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 中将行更改为列的主要内容,如果未能解决你的问题,请参考以下文章

如何在 SQL 中将列数据类型更改为 DOUBLE?

我在配置 apache 中将“Listen 80”行更改为“Listen 8080”,但它仍然不起作用

将某些行更改为列

将 WebStorm TSLint 错误行更改为警告行

jQuery:将表行更改为表单

如何在sql查询中将列更改为行