【问题标题】:Changing Rows to Column in SQL在 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)都有一个以用户和时间为行的新列。

【问题讨论】:

标签: sql sql-server tsql pivot


【解决方案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 或使用您的业务逻辑扩展它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-03
      • 1970-01-01
      • 1970-01-01
      • 2019-01-14
      • 2013-10-18
      • 1970-01-01
      相关资源
      最近更新 更多