我必須計算每個工作人員的班次時間。TSQL將行轉換爲列或將行分組
我寫了一個查詢,從我們的OLTP系統獲取數據並返回日期,員工及其登錄註銷時間。登錄和註銷時間是系統中的兩個單獨事務,但我希望在單行中登錄和註銷時間。看到下面的圖像,我得到的輸入和我想要的輸出。請幫助寫下一個查詢來實現我的目標。
我必須計算每個工作人員的班次時間。TSQL將行轉換爲列或將行分組
我寫了一個查詢,從我們的OLTP系統獲取數據並返回日期,員工及其登錄註銷時間。登錄和註銷時間是系統中的兩個單獨事務,但我希望在單行中登錄和註銷時間。看到下面的圖像,我得到的輸入和我想要的輸出。請幫助寫下一個查詢來實現我的目標。
你真正想要的是什麼lag()
功能,但不可用在SQL Server 2008中所以,你可以使用子查詢效仿:
select i.day, i.staff, i.login,
(select top 1 logout
from input i2
where i2.staff = i.staff and
i2.day = i.day and
i2.login = cast(login as date) and
i2.logout >= i.login
order by i2.logout
) as LogOut
from input i
where logout = cast(logout as date)
邏輯logout = cast(logout as date)
意以確定logout
對於時間分量具有零的行。
這裏假定沒有任何轉變會在午夜之後結束。
編輯:
在SQL Server 2012中,您可以使用相同的查詢。與lead()
替換它是一些工作:需要
select day, staff, login, logout
from (select i.day, i.staff, thedate as login, which,
lead(thedate) over (partition by staff, day order by date) as LogOut
from (select i.day, i.staff,
(case when login = cast(login as date) then logout
else login
end) as thedate,
(case when login = cast(login as date) then 'logout'
else 'login'
end) as which
from input i
) i
) i
where which = 'login'
更多的子查詢。問題在於你要比較兩個字段中的日期,所以最內層的子查詢將它們放在一個字段中('thedate'
)。接下來找到下一個日期(當一行是登錄時它假定是註銷,最外面只是選擇登錄行)。
說實話,我認爲我更喜歡第一個版本的子查詢,因爲你的數據結構
Gordon,我使用SQL Server2012。請修改查詢,並讓我知道如何使用滯後函數。謝謝 –
@RizwanMalik那麼爲什麼要使用[tag:sql-server-2008]標籤? – Lamak
我現在已經標記了Sql server 2012.請問您可以修改查詢,因爲上面的查詢沒有給出任何結果 –
當我必須對數據進行非規範化時,我喜歡使用自連接。我在SQL Server 2012上測試了以下內容。(但是,一般方法應該支持任何支持自連接的SQL RDBS,但是你必須修改的情況下,逐案的DATETIME2數據類型和函數調用)
數據:
DECLARE @t1 AS TABLE (
Day1 DATE
,Staff VARCHAR(3)
,Login DATETIME2
,Logout DATETIME2
);
INSERT INTO @t1
VALUES ('20130704', '123', '20130704 18:44:16.533', '20130704 00:00:00.000')
,('20130706', '456', '20130706 00:00:00.000', '20130706 01:10:12.000')
,('20130704', '123', '20130704 00:00:00.000', '20130704 20:24:16.553')
,('20130704', '123', '20130704 20:44:16.533', '20130704 00:00:00.000')
,('20130704', '123', '20130704 00:00:00.000', '20130704 22:54:16.553')
,('20130705', '456', '20130705 08:45:12.550', '20130705 00:00:00.000');
解決方案:
SELECT a.Day1, a.Staff, a.Login, MIN(b.Logout) AS Logout,
DateDiff(minute, a.login, MIN(b.logout)) AS Elapsed
FROM @t1 a join @t1 b
ON a.Staff = b.Staff AND a.Login < b.Logout AND CONVERT(TIME, a.Login) > '00:00:00.00'
GROUP BY a.Day1, a.Staff, a.Login;
其他注意事項:
DateDiff
的第一個參數hour
你的目的。)@Gordon Linoff
_I已經寫了一個查詢來獲取data_也許你應該考慮發佈你試過的查詢。 – Taryn