2015-10-14 67 views
-1

[myTable]有2個日期類型列:startD和endD,以及其他列類型。我想看看2015年的每一天都包含在區間[startD,結束]內統計一年中有多少天屬於一個區間

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 

此外,另一個問題:比方說,我想算10值多少都在365值。考慮到上面的代碼,我該如何做到這一點?

如果我改變t@t我得到Must declare the scalar variable "@t".

+0

你在哪看到'多部分標識符無法綁定'錯誤? – qxg

+0

我在哪裏添加註釋行 –

+1

你想實現什麼?我有一種感覺,就是打印'0s'和'1s'不是你的目標。 –

回答

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>[email protected] and A<@end) and (b>=A and B<[email protected]) then 1 else 0 end as result 
     from @t 

如果它不是你在找什麼,那麼你只需要在case條件下更改 邏輯。

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

+0

mytable可以包含startD/endD的重複項,例如:2015-01-01(startD) - 2015-02-01(endD)和2015-01-01(startD) - 2015-02-02(endD)。我應該考慮一個獨特的過濾器? –

+0

我用你的代碼來處理我的情況,結果是20k行。 Mytable包含1750行。 –

+0

@FlorinM。我的查詢爲原始表的每一行返回一行。你能設置一個sqlfiddle來證明你提到的問題嗎? –

0

根據您的要求:

我想看看2015年的每一天都是內部包含的 間隔

你可以的幫助下做到這一點a 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