2013-06-24 16 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,这是否有用?如果没有,我想删除它。 –