Sql server 在SQL Server中查找不连续的日期

Sql server 在SQL Server中查找不连续的日期,sql-server,tsql,gaps-and-islands,Sql Server,Tsql,Gaps And Islands,我想查找两个连续日期之间缺少的非连续日期 我正在发布我的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-1

我想查找两个连续日期之间缺少的非连续日期

我正在发布我的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           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
我在
中获得了两行
9
连续使用数据。您可以检查删除WHERE语句的结果。

在任何较新版本的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

为什么连续使用10和11?我看不出这些数字是从哪里来的。我希望连续的日期不被使用。如-7472381321最小日期2016-10-12,最大日期2016-10-14。之后,他于2016年10月24日开始使用。所以我不想要像7472381321 mindate 2016-10-15和maxdate-2016-10-23这样的日期,计数:8。我想要连续的不使用日期。如-7472381321最小日期2016-10-12,最大日期2016-10-14。之后,他于2016年10月24日开始使用。所以我不想使用像7472381321 mindate 2016-10-15和maxdate-2016-10-23这样的日期,并且计数:8。我认为您的示例是错误的,但我已经修改了我的响应。我已经修改了我的响应以进行优化,但您可以单击向上箭头;)谢谢你的回答。虽然我已经用SQL server的滞后分析窗口函数删除了内部子查询。但我希望不使用的连续日期。如-7472381321最小日期2016-10-12,最大日期2016-10-14。之后,他于2016年10月24日开始使用。所以我不想要像7472381321 mindate 2016-10-15和maxdate-2016-10-23这样的日期,计数:8。我想要连续的不使用日期。如-7472381321最小日期2016-10-12,最大日期2016-10-14。之后,他于2016年10月24日开始使用。因此,我不希望使用像7472381321 mindate 2016-10-15和maxdate-2016-10-23这样的日期,并计算:8.抱歉,但正如其他人已经评论的那样,您的样本数据和叙述与样本结果不匹配。