쿼리에서 누락 된 날짜 삽입


9

내가 만든 쿼리에서 누락 된 날짜를 삽입하는 방법 아래 결과 :

Date          Frequency
2014-05-18    5
2014-05-20    7
2014-05-25    7
2014-05-27    6

아래와 같이 결과에 0 값이없는 날짜가 있기를 원합니다.

Date          Frequency
2014-05-18    5
2014-05-19    0
2014-05-20    7
2014-05-21    0
2014-05-22    0
2014-05-23    0
2014-05-24    0
2014-05-25    7
2014-05-26    0
2014-05-27    6

서버에 대한 읽기 전용 액세스 권한이 있습니다.


쿼리를 사용하여 결과를 가져오고 있습니까? 또는 기간이 정의되어 있습니까? 당신은 당신의 쿼리 또는 테이블 추가 할 수 있습니다
vijayp

1
, 달력 테이블을 사용하여 그 선택하고 날짜별로 주파수에 가입 social.technet.microsoft.com/wiki/contents/articles/...
마크 Sinkinson

기본 테이블에서 결과를 가져 오기 위해 쿼리를 사용하고 있습니다.
Arvin

읽기 전용 액세스 권한 이 있으면 데이터베이스를 삽입하거나 업데이트하지 않아야합니다. 대신 DBA 팀에 도움을 요청하십시오.
Kin Shah

1
@ Kin 질문은 실제 데이터베이스 테이블에 행을 삽입하는 대신 결과 집합에 행을 삽입하려는 것을 의미한다고 생각합니다.
Mark Sinkinson

답변:


12

다음은 달력 테이블을 사용하는 예입니다 (실제로 가져야 함). 이 예제는 2014를 채우지 만 원하는만큼 몇 년 동안 채울 수 있습니다.

CREATE TABLE dbo.Calendar(d DATE PRIMARY KEY);

INSERT dbo.Calendar(d) SELECT TOP (365)
 DATEADD(DAY, ROW_NUMBER() OVER (ORDER BY number)-1, '20140101')
 FROM [master].dbo.spt_values
 WHERE [type] = N'P' ORDER BY number;

이제 쿼리는 간단합니다.

DECLARE @s DATE = '20140518', @e DATE = '20140527';

SELECT c.d, Frequency = COALESCE(s.Frequency,0)
  FROM dbo.Calendar AS c
  LEFT OUTER JOIN dbo.splunge AS s
  ON c.d = s.[date]
  WHERE c.d >= @s
    AND c.d < DATEADD(DAY, 1, @e);

SQLfiddle 예

달력 테이블을 만들 수 없으며 숫자 테이블이없는 경우 인라인으로 넣을 수 있습니다.

DECLARE @s DATE = '20140518', @e DATE = '20140527';

SELECT c.d, Frequency = COALESCE(s.Frequency,0)
  FROM 
(
   SELECT TOP (DATEDIFF(DAY, @s, @e)+1)
 DATEADD(DAY, ROW_NUMBER() OVER (ORDER BY number)-1, @s)
 FROM [master].dbo.spt_values
 WHERE [type] = N'P' ORDER BY number
) AS c(d)
  LEFT OUTER JOIN dbo.splunge2 AS s
  ON c.d = s.[date]
  WHERE c.d >= @s
    AND c.d < DATEADD(DAY, 1, @e);

SQLfiddle 예

날짜, 숫자 등의 집합 생성에 대한 자세한 내용은 다음 시리즈를 참조하십시오.


0
DECLARE @t TABLE(Dt Date,Frequency int)
INSERT INTO @t VALUES
('2014-05-18',5),('2014-05-20',7),('2014-05-25',7),('2014-05-27',6)



DECLARE @startDate DATE, @endDate DATE
SELECT @startDate = '2014-05-18', @endDate = '2014-05-27' --yyyy-mm-dd
;WITH Calender AS (
    SELECT @startDate AS CalanderDate
    UNION ALL
    SELECT DATEADD(day,1,CalanderDate) FROM Calender
    WHERE DATEADD(day,1,CalanderDate) <= @endDate
)
INSERT INTO @t SELECT
    Dt = CalanderDate,Frequency = 0

FROM Calender c
LEFT JOIN @t t 
ON t.Dt = c.CalanderDate
WHERE t.dt IS NULL
option (maxrecursion 0)

SELECT * FROM @t ORDER BY dt

깡깡이

2014-05-18  5
2014-05-19  0
2014-05-20  7
2014-05-21  0
2014-05-22  0
2014-05-23  0
2014-05-24  0
2014-05-25  7
2014-05-26  0
2014-05-27  6

재귀 적 CTE 접근법은 날짜 범위가 넓어짐에 따라 기하 급수적으로 더 비쌉니다. 이 목적을 위해 세트를 파생시키는보다 효율적인 방법이 있습니다.
Aaron Bertrand

@AaronBertrand 범위는 꽤 작지만 대안에 대한 링크는 무엇입니까?
Mihai

1
네, 여기는 작은 범위입니다. 문제는 사람들이이 접근법을 배우고 문제가되는 훨씬 더 큰 규모로 적용한다는 것입니다. 이 경우 "확인"이기 때문에 느린 접근 방식을 사용해야하는 이유는 무엇입니까? 내 대답을 참조하십시오.
Aaron Bertrand
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.