2016-10-26 173 views
0

我想在兩個連續日期之間找到missing NON-consecutive dates在SQL Server中查找不連續日期

我張貼我的SQL查詢和臨時表來找出結果。

但我沒有得到正確的結果

這裏是我的SQL查詢

drop table #temp 
    create table #temp(an varchar(20),dt date) 
    insert into #temp 
    select '2133783715' , '2016-10-16' union all 
    select '5107537880' , '2016-10-15' union all 
    select '6619324250' , '2016-10-15' union all 
    select '7146586717' , '2016-10-15' union all 
    select '7472381321' , '2016-10-12' union all 
    select '7472381321' , '2016-10-13' union all 
    select '7472381321' , '2016-10-14' union all 
    select '7472381321' , '2016-10-24' union all 
    select '8186056340' , '2016-10-15' union all 
    select '9099457123' , '2016-10-12' union all 
    select '9099457123' , '2016-10-13' union all 
    select '9099457123' , '2016-10-14' union all 
    select '9099457123' , '2016-10-23' union all 
    select '9099457123' , '2016-11-01' union all 
    select '9099457123' , '2016-11-02' union all 
    select '9099457123' , '2016-11-03' union all 
    select '9165074784' , '2016-10-16' 


drop table #final 
SELECT an,MIN(dt) AS MinDate,MAX(dt) AS MaxDate, COUNT(*) AS ConsecutiveUsage 
    --DateDiff(Day,LAG(MAX(dt)) OVER (partition by an ORDER BY an),MAX(dt)) nonusageDate 
into #final 
    FROM(
    SELECT an,dt, 
    DATEDIFF(D, ROW_NUMBER() OVER(partition by an ORDER BY dt),dt) AS Diff 
    FROM #temp c 
)P 
GROUP BY an,diff 

select * from #final order by 1 

an    MinDate  MaxDate  ConsecutiveUsage  
2133783715  2016-10-16 2016-10-16 1  
5107537880  2016-10-15 2016-10-15 1  
6619324250  2016-10-15 2016-10-15 1  
7146586717  2016-10-15 2016-10-15 1  
7472381321  2016-10-12 2016-10-14 3  
7472381321  2016-10-24 2016-10-24 1 
7472381321  2016-10-27 2016-10-28 1 
8186056340  2016-10-15 2016-10-15 1  
9099457123  2016-10-12 2016-10-14 3  
9099457123  2016-10-23 2016-10-23 1  
9165074784  2016-10-16 2016-10-16 1  

但我想的非使用日期結果。

我想獲得自10天以來一直未使用的AN。

所以這裏輸出應該是這樣的: -

an   minusagesdate maxusagedate  ConsecutiveNotUseddays  
    7472381321 2016-10-15  2016-10-23   9 
    7472381321 2016-10-25  2016-10-26   2 
    9099457123 2016-10-15  2016-10-22   8 

所以我只是想找出只有連續不使用日期數和他們的最小和最大的日期。

+0

爲什麼ConsecutiveNotUseddays 10和11?我看不到這些數字來自哪裏。 – BeanFrog

+0

我想連續使用未使用的日期。喜歡爲 - 7472381321最短日期2016-10-12和最大日期是2016-10-14。之後,他在2016-10-24開始使用。所以我不想用這種日期7472381321 mindate 2016-10-15和maxdate - 2016-10-23和計數:8。 –

回答

1

試試這個:

with ranked as (
    select f1.*, 
    ROW_NUMBER() over(partition by an order by dt) rang 
    from #temp f1 
    where exists 
    (select * from #temp f2 
    where f1.an=f2.an and datediff(day, f2.dt, f1.dt) >1 
) 
) 
    select an, minusagesdate, maxusagesdate, ConsecutiveNotUseddays 
    from (
    select f1.*, 
    DATEADD(DAY,1, (select f2.dt from ranked f2 where f1.an=f2.an and f2.rang+1=f1.rang)) minusagesdate , 
    DATEADD(DAY,-1, f1.dt) maxusagesdate , 
    datediff(day, (select f2.dt from ranked f2 where f1.an=f2.an and f2.rang+1=f1.rang), f1.dt) - 1 ConsecutiveNotUseddays 
    from ranked f1 
) tmp 
    where tmp.ConsecutiveNotUseddays>0 

或類似這樣的

with ranked as (
    select f1.*, 
    ROW_NUMBER() over(partition by an order by dt) rang 
    from #temp f1 
    where exists 
    (select * from #temp f2 
    where f1.an=f2.an and datediff(day, f2.dt, f1.dt) >1 
) 
) 
    select f1.an, 
    DATEADD(DAY,1, f3.dtbefore) minusagesdate , 
    DATEADD(DAY,-1, f1.dt) maxusagesdate , 
    datediff(day, f3.dtbefore, f1.dt) - 1 ConsecutiveNotUseddays 
    from ranked f1 
    outer apply 
    (
    select top 1 f2.dt as dtbefore from ranked f2 
    where f1.an=f2.an and f2.rang+1=f1.rang 
    ) f3 
    where datediff(day, f3.dtbefore, f1.dt) - 1>0 
+0

我想要連續使用未使用的日期。喜歡爲 - 7472381321最短日期2016-10-12和最大日期是2016-10-14。之後,他在2016-10-24開始使用。所以我不想用這種日期7472381321 mindate 2016-10-15和maxdate - 2016-10-23和計數:8。 –

+0

修改您的示例... – Esperento57

+0

您是否看到過我的更改?我想要的代碼.. –

0

它看起來像你想算MINDATE和每個an中的maxDate之間未使用的天數。如果是這樣的話,那麼這應該做的伎倆:

select an, min(dt) as min_dt, max(dt) as max_dt 
    , count(distinct dt) as daysused --this counts each day used, but only once 
    , datediff(day,min(dt),max(dt)) as totaldays --this is the total number of days between min and max date 
    , datediff(day,min(dt),max(dt)) - count(distinct dt) as daysnotused 
      --This takes total days - used days to give non-used days 
from #temp c 
group by an 
having datediff(day,min(dt),max(dt)) - count(distinct dt) >= 10 
+0

我想連續使用未使用的日期。喜歡爲 - 7472381321最短日期2016-10-12和最大日期是2016-10-14。之後,他在2016-10-24開始使用。所以我不想用這種日期7472381321 mindate 2016-10-15和maxdate - 2016-10-23和計數:8。 –

0

我的理解,你需要這樣的:

;WITH cte AS (
    SELECT an, 
      dt, 
      ROW_NUMBER() OVER (PARTITION BY an ORDER BY dt) as rn 
    FROM #temp 
) 

SELECT c1.an, 
     c1.dt MinDate, 
     c2.dt MaxDate, 
     DATEDIFF(day,c1.dt,c2.dt) as ConsecutiveNotUseddays 
FROM cte c1 
INNER JOIN cte c2 
    ON c1.an = c2.an AND c1.rn = c2.rn-1 
WHERE DATEDIFF(day,c1.dt,c2.dt) >= 10 

輸出:

an   MinDate  MaxDate  ConsecutiveNotUseddays 
7472381321 2016-10-14 2016-10-24 10 

對於9099457123我有兩排9ConsecutiveNotUseddays。您可以檢查刪除WHERE語句的結果。

0

在SQL Server的任何更新版本,這應該是很容易:

with x as (
    select *, lag(dt) over(partition by an order by dt) dt_lag 
    from #temp 
) 
select *, datediff(day, dt_lag, dt) 
from x 
where datediff(day, dt_lag, dt) >= 10 
+0

我想連續使用未使用的日期。喜歡爲 - 7472381321最短日期2016-10-12和最大日期是2016-10-14。之後,他在2016-10-24開始使用。所以我不想用這種日期7472381321 mindate 2016-10-15和maxdate - 2016-10-23和計數:8。 –

+0

對不起,但正如其他人已經評論過的那樣,請將您的樣本數據或您的敘述匹配樣本結果。 – dean