복붙노트

[SQL] SHOW ALL은 두 날짜 사이의 데이터를 날짜; 어떤 행이 특정 날짜에 대해 존재하지 않는 경우 모든 열이 제로를 표시

SQL

SHOW ALL은 두 날짜 사이의 데이터를 날짜; 어떤 행이 특정 날짜에 대해 존재하지 않는 경우 모든 열이 제로를 표시

나는 그 때 그것의 발 열에 제로 표시되어야없는 어떤 날짜 데이터가 두 날짜 사이의 날짜를 모두 보여주고 싶어요.

declare @temp table (
id int identity(1,1) not null,
CDate smalldatetime ,
val int
)

데이터에 대한 점검을위한 INSERT 문

insert into @temp select '10/2/2012',1
insert into @temp select '10/3/2012',1
insert into @temp select '10/5/2012',1
insert into @temp select '10/7/2012',2
insert into @temp select '10/9/2012',2
insert into @temp select '10/10/2012',2
insert into @temp select '10/13/2012',2
insert into @temp select '10/15/2012',2

월, 오늘의 첫 날 사이의 레코드를 검색

select * from @temp where CDate between '10/01/2012' AND '10/15/2012'

나는이 쿼리에게 그것의 쇼 나에게이 두 날짜 사이의 모든 데이터를 실행하지만 난에 또한 원하는 발 = 0 실종 날짜를 포함으로

SQL 바이올린 함께 샘플 데이터

해결법

  1. ==============================

    1.

    ;with d(date) as (
      select cast('10/01/2012' as datetime)
      union all
      select date+1
      from d
      where date < '10/15/2012'
      )
    select t.ID, d.date CDate, isnull(t.val, 0) val
    from d
    left join temp t
           on t.CDate = d.date
    order by d.date
    OPTION (MAXRECURSION 0) -- use this if your dates are >99 days apart
    

    여기 재귀 공통 테이블 표현식을 사용했습니다 있도록, 날짜를 확인해야합니다. SQL 바이올린

  2. ==============================

    2.이것은 한 이하 2천47일는에서와 날짜에 사이에 있기 때문에 작동합니다

    이것은 한 이하 2천47일는에서와 날짜에 사이에 있기 때문에 작동합니다

    declare @from smalldatetime = '10/01/2012'
    declare @to smalldatetime = '10/15/2012'
    
    select t.id, dateadd(day, number,@from), isnull(val, 0) val from @temp t
    right join master..spt_values s
    on dateadd(d, s.number, @from) = t.CDate
    where
    datediff(day, @from, @to ) > s.number
    and s.type = 'P'
    
  3. ==============================

    3.나는이 작업을 수행하는 가장 좋은 방법은 날짜와 자신의 테이블을 만들 생각 (당신은 또한 master.dbo.spt_values를 사용할 수 있지만, 나는 개인적으로 그 솔루션을 좋아하지 않는다)

    나는이 작업을 수행하는 가장 좋은 방법은 날짜와 자신의 테이블을 만들 생각 (당신은 또한 master.dbo.spt_values를 사용할 수 있지만, 나는 개인적으로 그 솔루션을 좋아하지 않는다)

    declare @Temp_Dates table (CDate datetime)
    declare @Date datetime
    select @Date = (select min(CDate) from temp)
    
    while @Date <= (select max(CDate) from temp)
    begin
        insert into @Temp_Dates (CDate)
        select @Date
    
        select @Date = dateadd(dd, 1, @Date)
    end
    
    select D.CDate, isnull(T.id, 0) as id
    from @Temp_Dates as D
        left outer join temp as T on T.CDate = D.CDate
    

    당신은 또한 CTE와 재귀 솔루션을 사용할 수 있습니다

  4. ==============================

    4.

    DECLARE @min DATETIME, 
            @max DATETIME, 
            @val INT 
    
    SELECT @min = Min(CDATE), 
           @max = Max(CDATE) 
    FROM   TEMP 
    
    DECLARE @temp TABLE 
      ( 
         CDATE SMALLDATETIME, 
         VAL   INT 
      ) 
    
    WHILE @min < @max 
      BEGIN 
          SELECT @val = VAL 
          FROM   TEMP 
          WHERE  CDATE = @min 
    
          INSERT @temp 
          VALUES (@min, 
                  @val) 
    
          SET @min = Dateadd(D, 1, @min) 
          SET @val = 0 
      END 
    
    SELECT * 
    FROM   @temp 
    
  5. ==============================

    5.

    Declare @temp Table(id int identity(1,1) not null,CDate smalldatetime ,val int)
    insert into @temp select '10/2/2012',1
    insert into @temp select '10/3/2012',1
    insert into @temp select '10/5/2012',1
    insert into @temp select '10/7/2012',2
    insert into @temp select '10/9/2012',2
    insert into @temp select '10/10/2012',2
    insert into @temp select '10/13/2012',2
    insert into @temp select '10/15/2012',2
    
    DECLARE @startDate DATE= '10/01/2012'
    DECLARE @endDate DATE= '10/15/2012'
    
    SELECT t.Id, X.[Date],Val = COALESCE(t.val,0)
    FROM 
        (SELECT [Date] = DATEADD(Day,Number,@startDate)  
        FROM  master..spt_values  
        WHERE Type='P' 
        AND DATEADD(day,Number,@startDate) <= @endDate)X
    LEFT JOIN  @temp t 
    ON X.[Date] = t.CDate
    

  6. ==============================

    6.최소 및 최대와 재귀 CTE를 사용

    최소 및 최대와 재귀 CTE를 사용

    declare @T table (id int identity(1,1) primary key, dt date not null, val int not null);
    insert into @T (dt, val) values 
           ('10/2/2012',1)
         , ('10/3/2012',1)
         , ('10/5/2012',1)
         , ('10/7/2012',2)
         , ('10/9/2012',2)
         , ('10/10/2012',2)
         , ('10/13/2012',2)
         , ('10/15/2012',2);
    --select * from @T;
    with cte as 
    ( select min(dt) as dt, max(dt) as mx 
      from @T 
      union all 
      select dateadd(dd, 1, dt), mx 
      from CTE 
      where dt < mx
    )
    select c.dt, isnull(t.val, 0) as val 
    from cte c
    left join @T t
    on c.dt = t.dt
    order by c.dt
    option (maxrecursion 0);
    
    dt         val
    ---------- -----------
    2012-10-02 1
    2012-10-03 1
    2012-10-04 0
    2012-10-05 1
    2012-10-06 0
    2012-10-07 2
    2012-10-08 0
    2012-10-09 2
    2012-10-10 2
    2012-10-11 0
    2012-10-12 0
    2012-10-13 2
    2012-10-14 0
    2012-10-15 2
    
  7. from https://stackoverflow.com/questions/12890967/show-all-dates-data-between-two-dates-if-no-row-exists-for-particular-date-then by cc-by-sa and MIT license