根据另一列的值条件在SQL中添加/选择多列

问题描述

我正在使用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

任何帮助将不胜感激!

解决方法

您可以使用聚合:

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;

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

但是,这种情况可能会变得非常复杂。如果这正是您真正需要的,您应该问一个 new 问题。确保包含对给定类型的多次/缺失交易时该怎么做的解释-或清楚地解释为什么这是不可能的。

,

我认为这样可以做到:

    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,TransactionDateTime AS ClockOutTime
    FROM TableA 
    WHERE TransactionType = 2
   ) b
   ON a.UserId = b.UserId 

我还没有测试过-只是直接编写它,但我认为它应该可以工作,当然,您想要的是带有联接的子查询。

,

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

Select UserId,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;