1

ここで質問、

attendance私は4列で呼ばれるテーブルを持っています:

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

私が達成したいのは、最初のチェックインとチェックアウトの時間と最後のチェックインとチェックアウトの時間を取得することです。テーブルにチェックインとチェックアウトの行が 1 つしかない場合は、同じものを返します。

次のようなサンプル データ:

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 |

dateandtimedatetimeデータ型として保存することを強くお勧めします。

注:提供されたサンプル データと一致するように、値をClock In/Clock OutからCheck 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 に答える