2016-07-29 56 views
0

我們有一個爲人們服務的規定的表。例如:如何找到在衆多行連續的日期在SQL Server

id people_id dateStart dateEnd 
1 1   28.07.14 19.07.16 
2 2   14.04.15 16.02.16 
3 2   16.02.16 18.04.16 
4 2   18.04.16 27.06.16 
5 2   27.06.16 19.07.16 
6 2   19.07.16 NULL 
7 3   24.02.12 17.06.12 
8 3   23.07.12 19.09.12 
9 3   18.08.14 NULL 
10 4   28.06.15 NULL 
11 5   19.01.16 NULL 

我需要的是持續時間超過一年以上再算上天通未完成不間斷服務的實際開始日期,提取不同people_id的(客戶)。兩個不同行的「開始日期」和「結束日期」應該是相同的,並計爲連續的。一個客戶只能有一個未完成的服務。
所以表的完美效果上面會:

people_id dateStart lasts(days) 
2   14.04.15 472 
3   18.08.14 711 
4   28.06.15 397 

我沒有問題,跟單服務:

SELECT 
    --some other columns from PEOPLE, 
    p.PEOPLE_ID, 
    s.DATESTART, 
    DATEDIFF(DAY, s.DATESTART, GETDATE()) as lasts 
FROM 
    PEOPLE p 
    INNER JOIN service s on s.ID = 
    (
     SELECT TOP 1 s2.ID 
     FROM service s2 
     WHERE s2.PEOPLE_ID = p.PEOPLE_ID 
      AND s2.DATESTART IS NOT NULL 
      AND s2.DATEEND IS NULL 
     ORDER BY s2.DATESTART DESC 
    ) 
WHERE 
    DATEDIFF(DAY, s.DATESTART , GETDATE()) >= 365 

但我無法弄清楚如何確定連續服務。

+0

如果'dateEnd '是'null',這是否意味着它正在進行? – Ash

+0

@AshwinNair是的。我只需要活躍的客戶。如果有人沒有'dateEnd = NULL'的任何服務,他**不**活躍。 –

+0

你正在使用什麼版本的SQL Server? – Squirrel

回答

1

你可以找到這裏的「連續」的服務時段開始使用lag()。然後這個標誌的累加值提供了一組,它可用於聚合:

select people_id, min(datestart) as datestart, 
     (case when count(dateend) = count(*) then max(dateend) end) as dateend 
from (select t.*, 
      sum(case when prev_dateend = datestart then 0 else 1 end) over 
       (partition by people_id order by datestart) as grp 
     from (select t.*, 
        lag(dateend) over (partition by people_id order by date_start) as prev_dateend 
      from t 
      ) t 
    ) t 
group by people_id, grp 
having count(*) > count(dateend); 
+0

這個查詢似乎沒有得到OP要求的天數('lasts(days)'列)。 – Ash

+0

OP只需要使用DATEDIFF()來獲取 – Squirrel

+0

所以你同意它沒有完成,以及隨後的日子:)。我很好奇,試過這個查詢,我得到4行而不是3,所以OP需要添加'> = 365'的檢查。另外,我在'dateend'列下的所有行都得到'NULL'。 – Ash

0

嘗試此查詢:

select PeopleId, min(dateStart) as dateStart, sum(diff) as [lasts(days)] from 
(
    select P.*, datediff(day,datestart, DateEnd) as diff from 
     (select peopleId, dateStart, 
     isnull(dateend, cast(getdate() as date)) as DateEnd 
     from People 
     ) P 
    where Dateend in 
     (select DateStart from People 
      where PeopleId = P.PeopleId) 
      or DateEnd = cast(getdate() as date) -- check for continuous dates 
) P1 group by PeopleId having sum(diff)> 365  --check for > one year 

查詢中的註釋應該解釋的事情

+0

謝謝。一般而言,你是對的,但忘了另一個條款。客戶端應至少有一行'DateEnd IS NULL'(即活動)。所以我添加了這個條款,現在一切似乎都沒問題。 –

+0

很高興有幫助。 – Ash