我正在使用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
任何帮助将不胜感激!
答案 0 :(得分: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;
这适用于您的示例数据,因为每个用户最多有两行。如果您的真实数据更复杂,则每个数据将仅返回最大值。
但是,这种情况可能会变得非常复杂。如果这正是您真正需要的,您应该问一个 new 问题。确保包含对给定类型的多次/缺失交易时该怎么做的解释-或清楚地解释为什么这是不可能的。
答案 1 :(得分:0)
我认为这样可以做到:
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
我还没有测试过-只是直接编写它,但我认为它应该可以工作,当然,您想要的是带有联接的子查询。
答案 2 :(得分:0)
该表可以保持自身连接。如果用户一遍又一遍地进出,这种方法可能会很有用(带有额外的日期不平等)。
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;