在 SQL 服务器中查找非连续日期

Find Non Consecutive date in SQL Server

我想找到两个连续日期之间的missing NON-consecutive dates

我正在发布我的 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

所以我只想找出连续未使用的日期计数及其最小和最大日期。

试试这个:

  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 

您似乎在计算每个 an 的 mindate 和 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

据我所知,您需要这个:

;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,我在 ConsecutiveNotUseddays 中得到了两行 9。您可以检查删除 WHERE 语句的结果。

在任何较新版本的 SQL 服务器上,这应该很容易:

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