TSQL:全年/每个月的连续期间

问题描述 投票:0回答:1

[我尝试查找所有在2018年期间每月至少有一天会员资格的Cust。我想出了一种在每个月初/中/月末检查其会员资格的解决方案,如下面的代码段所示,但尝试查找更多智能解决方案。

我知道我可以在365天的每一天内使用计数表进行检查,但是可能有更优雅的解决方案?我对SQL有点陌生,我认为我在GROUPING区域中缺少某些内容。

在下面显示的代码段中,两个Cust都有至少一天的会员资格。全部发送。

所需的输出:

CustID
------
   1
  22

代码:

with data as 
(
    select * 
    from (values (1, 1,   '2017-12-11', '2018-01-16'),   (1, 22,  '2018-01-28', '2018-03-9' ), (1, 333, '2018-03-1', '2018-12-31') ,  -- island
                 (22, 1,  '2017-12-31', '2018-01-11'),   (22, 2,  '2017-2-11',  '2019-12-31')) as t (CustID, ContractID, StartDD, EndDD)     ---      
    )
    select 
        isdate(startDD), isdate(EndDD) 
    from 
        data
), gaps as 
(
    select  
        *,  
        datediff(day, lag(EndDD, 1, StartDD) over (partition by CustID order by StartDD), StartDD) as BreakDD          -- negative is island
    from 
        data
)
select 
    *, 
    datepart(month,StartDD) mmS , datepart(month,EndDD) mmE 
from 
    gaps 
    -- and was active any 1+ day during each of the 12 months in 2018    ????
where 
    1 = 1 
    /* and (cast('1/1/2018' as date) between StartDD and EndDD
            or cast('1/15/2018' as date) between StartDD and EndDD     
            or cast('1/31/2018' as date) between StartDD and EndDD)
       ---- etc..  for each month
       and (      cast('12/1/2018'  as date)   between  StartDD  and  EndDD 
              or  cast('12/15/2018' as date)   between  StartDD  and  EndDD  
              or  cast('12/31/2018' as date)   between  StartDD  and  EndDD  
           ) 
*/ 
--select CustID, max(BreakDD) Max_Days
--from gaps
--group by CustID
sql-server tsql
1个回答
0
投票
尝试此答案。

首先创建一个函数,以返回给定日期之间的所有月份和年份。

功能:

--SELECT * FROM dbo.Fn_GetMonthYear('2017-12-11','2018-01-16') ALTER FUNCTION dbo.Fn_GetMonthYear(@StartDate DATETIME,@EndDate DATETIME) RETURNS TABLE AS RETURN( SELECT DATEPART(MONTH, DATEADD(MONTH, x.number, @StartDate)) AS [Month] ,DATEPART(YEAR, DATEADD(MONTH, x.number, @StartDate)) AS [Year] FROM master.dbo.spt_values x WHERE x.type = 'P' AND x.number <= DATEDIFF(MONTH, @StartDate, @EndDate) )

表模式:

CREATE TABLE #t(CustID INT, ContractID INT, StartDD date, EndDD date) INSERT INTO #t values (1, 1, '2017-12-11', '2018-01-16'), (1, 22, '2018-01-28', '2018-03-9' ), (1, 333, '2018-03-1', '2018-12-31') , -- island (22, 1, '2017-12-31', '2018-01-11'), (22, 2, '2017-2-11', '2019-12-31')
这是您的要求的

T-SQL查询

SELECT CustID ,COUNT(DISTINCT [Month]) NoOfMonths FROM( SELECT * FROM #t t CROSS APPLY dbo.Fn_GetMonthYear(StartDD,EndDD) )D WHERE [Year] = 2018 GROUP BY CustID HAVING COUNT(DISTINCT [Month])=12

结果:

CustID NoOfMonths 1 12 22 12
© www.soinside.com 2019 - 2024. All rights reserved.