1

这里的问题,

我有一个名为attendance4 列的表:

[Username] varchar(256)
[Date] varchar(256)
[Time] varchar(256)
[Action] varchar(256)

我希望实现的是获得第一次入住和退房时间和最后一次入住和退房时间。如果表中只有一个签入和签出行,则返回相同。

样例数据如下:

Username | Date       | Time     | Action
--------------------------------------------
User1    | 01/12/2012 | 12:54:41 | Check In
User1    | 01/12/2012 | 18:26:36 | Check Out
User1    | 01/12/2012 | 18:44:17 | Check In
User1    | 01/12/2012 | 22:05:31 | Check Out

我的预期结果如下所示:

Output:
Username | Date       | First In | First Out | Last In  | Last Out
User1    | 01/12/2012 | 12:54:41 | 18:26:36  | 18:44:17 | 22:05:31

我试过这个 SQL 语句:

SELECT [USERNAME], [DATE]
, min(case when [action] = 'Clock In' then [time] else '' end) as 'First in'
, min(case when [action] = 'Clock Out' then [time] else '' end )as 'First out'
, max(case when [action] = 'Clock In' then [time] else '' end) as 'Last in'
, max(case when [action] = 'Clock Out' then [time] else '' end )as 'Last out'
FROM attendance
WHERE [USERNAME] = 'User1' AND [DATE] = '01/12/2012'
group by [username],[date]

它返回意外结果,即我的最小值始终为“”或为空,但我的最大值“后进”和“后出”均处于正确值。

Output:
Username | Date       | First In | First Out | Last In  | Last Out
User1    | 01/12/2012 |          |           | 18:44:17 | 22:05:31

我的 SQL 有什么问题吗?

任何人都可以提出任何建议吗?

4

3 回答 3

2

我会这样做略有不同使用row_number()

select username, date,
  max(case when [action] = 'Check In' and rn=1 then time end) FirstIn,
  max(case when [action] = 'Check Out' and rn=1 then time end) FirstOut,
  max(case when [action] = 'Check In' and rn=2 then time end) LastIn,
  max(case when [action] = 'Check Out' and rn=2 then time end) LastOut
from
(
  select username, cast(date as date) date, 
    cast(time as time) time, 
    action,
    row_number() 
      over(partition by username, cast(date as date), action
           order by cast(time as time)) rn
  from attendance
) src
group by username, date;

请参阅带有演示的 SQL Fiddle

结果是:

| USERNAME |       DATE |          FIRSTIN |         FIRSTOUT |           LASTIN |          LASTOUT |
-----------------------------------------------------------------------------------------------------
|    User1 | 2012-01-12 | 12:54:41.0000000 | 18:26:36.0000000 | 18:44:17.0000000 | 22:05:31.0000000 |

我强烈建议您将dateand存储timedatetime数据类型。

注意:我将值从Clock In/更改Clock OutCheck In/Check Out以匹配您提供的示例数据。

于 2013-01-07T10:15:07.870 回答
1

试试这个:

SELECT [USERNAME], [DATE]
, min(case when [action] = 'Clock In' then [time]  end) as 'First in'
, min(case when [action] = 'Clock Out' then [time] end )as 'First out'
, max(case when [action] = 'Clock In' then [time] end) as 'Last in'
, max(case when [action] = 'Clock Out' then [time] end )as 'Last out'
FROM attendance
WHERE [USERNAME] = 'User1' AND [DATE] = '01/12/2012'
group by [username],[date]

你明白问题出在哪里了吗?

于 2013-01-07T10:08:55.277 回答
0

我的解决方案是创建一个存储过程:

DECLARE @first_in VARCHAR, @first_out VARCHAR, @last_in VARCHAR, @last_out VARCHAR
BEGIN
SELECT TOP 1
     @first_in = time
FROM attendance
WHERE [USERNAME] = 'User1' AND [DATE] = '01/12/2012' AND [ACTION] = 'first in'
ORDER BY time ASC


SELECT TOP 1
     @first_in = time
FROM attendance
WHERE [USERNAME] = 'User1' AND [DATE] = '01/12/2012' AND [ACTION] = 'first out'
ORDER BY time ASC

SELECT TOP 1
     @last_in = time
FROM attendance
WHERE [USERNAME] = 'User1' AND [DATE] = '01/12/2012' AND [ACTION] = 'first in'
ORDER BY time DESC

SELECT TOP 1
     @last_out = time
FROM attendance
WHERE [USERNAME] = 'User1' AND [DATE] = '01/12/2012' AND [ACTION] = 'first out'
ORDER BY time DESC

SELECT 'User1','01/12/2012', @first_in, @first_out, @last_in, @last_out
END
于 2013-01-07T10:13:47.400 回答