【问题标题】:Add/Select mulitiple columns in SQL based on another column's value condition根据另一列的值条件在 SQL 中添加/选择多个列
【发布时间】:2020-08-16 06:38:54
【问题描述】:

我正在使用 SQL Server。这是场景:

假设我有一个 tableA

UserId  UserName  TransactionType   TransactionDateTime
1       Staff1    NULL              NULL
2       Staff2    1                 2020-08-12 03:11:20.4871383
2       Staff2    2                 2020-08-12 03:41:33.4850314
3       Staff3    2                 2020-08-12 03:41:33.4848626
3       Staff3    1                 2020-08-12 03:11:20.4869688

我想查询如下结果:

UserId  UserName  ClockInTime                     ClockOutTime
1       Staff1    NULL                            NULL
2       Staff2    2020-08-12 03:11:20.4871383     2020-08-12 03:41:33.4850314
3       Staff3    2020-08-12 03:11:20.4869688     2020-08-12 03:41:33.4848626

所以条件是type为1则transactiondatetime为clockintime,type为2则为clockouttime。

我尝试使用“case when”:

Select UserId, UserName, 
case when TransactionType = 1 Then TransactionDateTime else null End as ClockInTime,
case when TransactionType = 2 Then TransactionDateTime else null End as ClockOutTime
From tableA

这样会返回 5 行:

UserId  UserName    ClockInTime                  ClockOutTime
1       Staff1      NULL                         NULL
2       Staff2      2020-08-16 03:11:20.4871383  NULL
2       Staff2      NULL                         2020-08-16 03:41:33.4850314
3       Staff3      NULL                         2020-08-16 03:41:33.4848626
3       Staff3      2020-08-16 03:11:20.4869688  NULL

非常感谢任何帮助!

【问题讨论】:

  • 请告诉我们你尝试了什么。

标签: sql sql-server datetime datetime2


【解决方案1】:

你可以使用聚合:

select UserId, UserName, 
       max(case when TransactionType = 1 Then TransactionDateTime End) as ClockInTime,
       max(case when TransactionType = 2 Then TransactionDateTime End) as ClockOutTime
from tableA
group by UserId, UserName;

这适用于您的示例数据,因为每个用户最多有两行。如果您的真实数据更复杂,这将只返回每个数据的最大值。

但是,这种情况可能会变得相当复杂。如果这是你真正需要的,你应该问一个新的问题。一定要说明当给定类型的交易有多个/缺失时该怎么做——或者清楚地解释为什么这是不可能的。

【讨论】:

    【解决方案2】:

    我认为这样的事情可以做到:

        SELECT a.UserId, 
               a.UserName,
               CASE WHEN a.TransactionType = 1 
                    THEN a.TransactionDateTime 
                    ELSE null END AS ClockInTime,
               b.ClockOutTime
        FROM TableA a
        LEFT JOIN ( 
        
        SELECT UserId, 
               UserName,
               TransactionDateTime AS ClockOutTime
        FROM TableA 
        WHERE TransactionType = 2
       ) b
       ON a.UserId = b.UserId 
    

    我没有对此进行测试 - 只是直接编写它,我认为它应该可以工作,当然你想要一个带有连接的子查询。

    【讨论】:

      【解决方案3】:

      该表可以保持连接到自身。如果用户一遍又一遍地打卡和打卡,这种方法可能很有用(带有额外的日期不等式)。

      Select UserId, UserName, ct1.TransactionDateTime ClockInTime, ct2.TransactionDateTime ClockOutTime
      From tableA ta  left join tableA tb on ta.UserId=tb.UserId
      where ta.TransactionType = 1 and tb.TransactionType = 2;
      

      【讨论】:

        猜你喜欢
        • 2012-01-30
        • 1970-01-01
        • 2013-08-21
        • 1970-01-01
        • 2015-11-05
        • 2020-10-24
        • 1970-01-01
        • 2021-12-02
        • 1970-01-01
        相关资源
        最近更新 更多