2013-06-24 39 views
0

我有一張僱員支付表。他們走動了很多,我需要總結的數據發現:T-SQL DENSE_RANK - 不完全

一)在工作間隙日期 b)工作地點的)島嶼 ç算星期的島嶼

這聽起來相當平直向前,但它讓我發瘋。

到目前爲止,我有一個查詢,它獲取最小和最大payment_date之間的所有可能支付日期。然後我加入付款文件。然後我需要總結這些數據,忽略薪酬差距不到3周。

這裏是我到目前爲止的代碼(我已經離開的一些多餘的東西):

declare @Start date declare @End date 
select @Start=(select min(pay_date) from Location_ANALYSIS where ni_code='AN NI Number'), @End=(select max(pay_date) from Location_ANALYSIS where ni_code='AN NI Number') 

WITH sample AS (
SELECT @Start AS dt 
UNION ALL 
SELECT DATEADD(dd, 7, dt) 
FROM sample 
WHERE DATEADD(dd, 7, dt) <= @End) 
select sample.dt, isnull(o.Location_id,'{unknown}') as Location, sum(isnull(gross_pay,0)),isnull(cast(min(pay_date) as date),dt) as FirstDate,isnull(cast(dateadd(d,6,min(pay_date)) as date),dateadd(d,6,dt)) as LastDate 
,GroupSequence = DENSE_RANK() over (order by isnull(o.Location_id,'{unknown}')) 
from sample 
left outer join Location_ANALYSIS o on o.PAY_DATE>=sample.dt and o.PAY_DATE<=DATEADD(d,6,sample.dt) and o.NI_CODE='AN NI Number' 
group by isnull(o.Location_id,'{unknown}'),sample.dt 
order by sample.dt 

這給了我這個名單:

dt Location(No column name) FirstDate LastDate GroupSequence 
2012-04-06 LONDON 900.75 2012-04-06 2012-04-12 2 
2012-04-13 LONDON 555.75 2012-04-13 2012-04-19 2 
2012-04-20 LONDON 244.53 2012-04-20 2012-04-26 2 
2012-04-27 LONDON 524.58 2012-04-27 2012-05-03 2 
2012-05-04 LONDON 500.58 2012-05-04 2012-05-10 2 
2012-05-11 LONDON 467.58 2012-05-11 2012-05-17 2 
2012-05-18 LONDON 258.78 2012-05-18 2012-05-24 2 
2012-05-25 LONDON 479.58 2012-05-25 2012-05-31 2 
2012-06-01 {unknown} 0.00 2012-06-01 2012-06-07 1 
2012-06-08 {unknown} 0.00 2012-06-08 2012-06-14 1 
2012-06-15 {unknown} 0.00 2012-06-15 2012-06-21 1 
2012-06-22 {unknown} 0.00 2012-06-22 2012-06-28 1 
2012-06-29 {unknown} 0.00 2012-06-29 2012-07-05 1 
2012-07-06 LONDON 186.08 2012-07-06 2012-07-12 2 
2012-07-13 {unknown} 0.00 2012-07-13 2012-07-19 1 
2012-07-20 {unknown} 0.00 2012-07-20 2012-07-26 1 
2012-07-27 {unknown} 0.00 2012-07-27 2012-08-02 1 
2012-08-03 {unknown} 0.00 2012-08-03 2012-08-09 1 
2012-08-10 {unknown} 0.00 2012-08-10 2012-08-16 1 
2012-08-17 LONDON 767.58 2012-08-17 2012-08-23 2 
2012-08-24 LONDON 758.58 2012-08-24 2012-08-30 2 
2012-08-31 LONDON 794.58 2012-08-31 2012-09-06 2 
2012-09-07 LONDON 389.58 2012-09-07 2012-09-13 2 
2012-09-14 LONDON 428.58 2012-09-14 2012-09-20 2 
2012-09-21 LONDON 629.58 2012-09-21 2012-09-27 2 
2012-09-28 LONDON 734.58 2012-09-28 2012-10-04 2 

我的問題是我現在的位置需要組但是可以重複該位置,因此不能使用DENSE_RANK()值進行分組。

我需要這樣的數據:

dt Location (No column name) FirstDate LastDate GroupSequence 
2012-04-06 LONDON 900.75 2012-04-06 2012-04-12 1 
2012-04-13 LONDON 555.75 2012-04-13 2012-04-19 1 
2012-04-20 LONDON 244.53 2012-04-20 2012-04-26 1 
2012-04-27 LONDON 524.58 2012-04-27 2012-05-03 1 
2012-05-04 LONDON 500.58 2012-05-04 2012-05-10 1 
2012-05-11 LONDON 467.58 2012-05-11 2012-05-17 1 
2012-05-18 LONDON 258.78 2012-05-18 2012-05-24 1 
2012-05-25 LONDON 479.58 2012-05-25 2012-05-31 1 
2012-06-01 {unknown} 0.00 2012-06-01 2012-06-07 2 
2012-06-08 {unknown} 0.00 2012-06-08 2012-06-14 2 
2012-06-15 {unknown} 0.00 2012-06-15 2012-06-21 2 
2012-06-22 {unknown} 0.00 2012-06-22 2012-06-28 2 
2012-06-29 {unknown} 0.00 2012-06-29 2012-07-05 2 
2012-07-06 LONDON 186.08 2012-07-06 2012-07-12 3 
2012-07-13 {unknown} 0.00 2012-07-13 2012-07-19 4 
2012-07-20 {unknown} 0.00 2012-07-20 2012-07-26 4 
2012-07-27 {unknown} 0.00 2012-07-27 2012-08-02 4 
2012-08-03 {unknown} 0.00 2012-08-03 2012-08-09 4 
2012-08-10 {unknown} 0.00 2012-08-10 2012-08-16 4 
2012-08-17 LONDON 767.58 2012-08-17 2012-08-23 5 
2012-08-24 LONDON 758.58 2012-08-24 2012-08-30 5 
2012-08-31 LONDON 794.58 2012-08-31 2012-09-06 5 
2012-09-07 LONDON 389.58 2012-09-07 2012-09-13 5 
2012-09-14 LONDON 428.58 2012-09-14 2012-09-20 5 
2012-09-21 LONDON 629.58 2012-09-21 2012-09-27 5 
2012-09-28 LONDON 734.58 2012-09-28 2012-10-04 5 

這樣我就可以通過計算組項目由GroupSequence和組忽略子3個星期的差距。

最後,我想產生這樣:

Location START_DATE END_DATE PERIOD TURNOVER 
London 2012-04-06 2012-05-31 8 3932.13 
{unknown} 2012-06-01 2012-07-05 5 0.00 
London 2012-07-06 2012-07-05 0 186.08 
{unknown} 2012-07-13 2012-08-16 5 0.00 
London 2012-08-17 2012-10-04 7 4503.06 

對於它的價值,我有已經在使用遊標和大量迭代的這個工作,但也有150萬條的付款記錄現在,我拼命地試圖通過裝箱遊標來加快速度。

我希望這是有道理的

+0

哪個版本的SQL Server?鉛/滯後(2012年)會有所幫助。否則,你可能最終會自動加入子查詢來尋找休息時間。 – JAQFrost

回答

0

我對SQL 2012醜陋的解決方案,我不想分享。問題是我需要一個窗口函數來處理另一個窗口函數的結果。所以我不得不把我的第一個結果放到一個臨時表中,然後在CTE中查詢臨時表,然後將其分組,最終得到他想要的結果。看起來不正確。此外,我的示例數據不同,但適用於此問題。

我認爲好的部分可能是窗口函數的使用。

在我的第一部分中,我每次使用滯後都會更改位置。

CASE WHEN Location != LAG(Location, 1, 0) OVER (ORDER BY dt) THEN 1 
ELSE 0 END [change] 

結果看起來像

Location, change, other_fields... 
Montreal, 1, ... 
Montreal, 0, ... 
London, 1, ... 
Miami, 1, ... 
Montreal, 1, ... 

在下一部分中,我得到一個數字,每一個位置出現的一個新實例的時間增量。

SUM(change) OVER (-- I had a partition, but that isn't required 
        ORDER BY dt 
        ROWS UNBOUNDED PRECEDING) [change_id] 

這些結果如下:

Location, change_id, other_fields... 
Montreal, 1, ... 
Montreal, 1, ... 
London, 2, ... 
Miami, 3, ... 
Montreal, 4, ... 

然後我就可以GROUP BY CHANGE_ID,從CTE位置,以創建最終輸出。

Location, sum_of_sales, other_aggregate_fields... 
Montreal, 100, ... 
London, 75, ... 
Miami, 160, ... 
Montreal, 75, ... 
+0

嗨,感謝您抽出時間發帖,但我不認爲這是答案。我的問題是,即使位置已經出現,我也需要增加值。所以,蒙特利爾,蒙特利爾1,倫敦1,邁阿密2,蒙特利爾3,蒙特利爾4,倫敦4,倫敦5, – Deadeye

+0

是的,我的例子很糟糕,我已經糾正了它。但這會起作用。會發生什麼情況是,每當位置從前一行更改爲'1'時,值爲1.因此,如果行是蒙特利爾,倫敦,倫敦,蒙特利爾,則會導致第一個查詢中的1,1,0,1,和第二,一,二,三。此外,這兩種查詢的順序必須保持一致,這給我帶來了麻煩。 –

+0

@ user1753793,這是否有用?如果沒有,我想刪除它。 –