计算一年中有多少天属于一个区间

时间:2015-10-14 05:53:01

标签: sql sql-server

[myTable]有两个日期类型列:startD和endD,以及其他列类型。我想知道2015年的每一天是否都包含在[startD,end]

的区间内
declare @t table ( A date, B date )
    insert into @t (A,B)
    select distinct startD, endD
    from myTable


    declare @start date = '2015-01-01'
    while @start < '2016-01-01'
    begin
    select 
     case
        when  @start >= @t.A and @start <= @t.B
            then 1
            else 0
      end as it
    from @t 
    set @start = DateAdd(day,1,@start) 
    end

另外,另一个问题是:假设我想计算1值中0365个值的数量。考虑到上面的代码,我怎样才能做到这一点?

如果我将t更改为@t,我会Must declare the scalar variable "@t".

3 个答案:

答案 0 :(得分:0)

你不能使用

if @start >= t.A and @start <= t.B -- how can I reffer to t.A and t.B ?

试试这个

select case when @start >= A and @start <=B then 1 else 0 end as result
from @t 

之后,您可以逐个打印所有结果值。

,或者

  

(希望)解决方案:(我不确定你真正想要什么,不清楚,但希望这个'   帮助你)

declare @start date = '2015-01-01'
declare @end date = '2016-01-01'

     select case when (A>=@start and A<@end) and (b>=A and B<=@end) then 1 else 0 end as result
        from @t 
  

如果它不是你想要的那么你只需要改变   case条件下的逻辑。

答案 1 :(得分:0)

您可以使用DATEDIFF计算天数:

SELECT IIF(y.days >=0, y.days + 1, 0) AS numOfDays
FROM mytable
CROSS APPLY (
  SELECT IIF('20150101' > startD, '20150101', startD),
         IIF('20151231' < endD, '20151231', endD) ) AS x([from],[to])
CROSS APPLY (SELECT DATEDIFF(d, x.[from], x.[to])) AS y(days)         

上述查询统计了表格[startD, end]中包含的2015年的天数。

Demo here

答案 2 :(得分:0)

根据您的要求:

  

我想知道2015年的每一天是否都包含在内   间隔

您可以在Tally Table的帮助下完成此操作:

SQL Fiddle

--Prepare sample data
DECLARE @t TABLE(startD DATE, endD DATE)
INSERT INTO @t VALUES
('20150101', '20150125'),
('20150301', '20150313');

DECLARE @year INT = 2015
DECLARE @numberOfDays INT

SELECT @numberOfDays = DATEDIFF(DAY, DATEADD(YEAR, @year - 1900, 0), DATEADD(YEAR, @year + 1 - 1900, 0))

;WITH E1(N) AS(
    SELECT 1 FROM(VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))t(N)
),
E2(N) AS(SELECT 1 FROM E1 a CROSS JOIN E1 b),
E4(N) AS(SELECT 1 FROM E2 a CROSS JOIN E2 b),
Tally(N) AS(
    SELECT TOP(@numberOfDays)
        ROW_NUMBER() OVER(ORDER BY (SELECT NULL))
    FROM E4
),
CteAllDates(dt) AS(
    SELECT
        CAST(DATEADD(DAY, N-1, DATEADD(YEAR, @year - 1900, 0)) AS DATE)
    FROM Tally
)
SELECT
    [Date]           = d.dt,
    [Is_In_Interval] = CASE WHEN t.startD IS NULL THEN 0 ELSE 1 END
FROM CteAllDates d
LEFT JOIN @t t
    ON d.dt BETWEEN t.startD AND t.endD