Вставте пропущені дати з запиту


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/…
Марк Сінкінсон

Я використовую запит, щоб отримати результат із головної таблиці.
Арвін

Якщо ви читали лише доступ, вам не слід вставляти або оновлювати базу даних. Замість цього попросіть команду DBA допомогти вам.
Кін Шах

1
@Kin Я думаю, що питання означає, що вони хочуть вставити рядки в набір результатів, а не вставляти рядки у фактичну таблицю бази даних.
Марк Сінкінсон

Відповіді:


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 стає дорожче експоненціально, оскільки діапазон дат стає ширшим. Існують більш ефективні способи отримання наборів для цієї мети.
Аарон Бертран

@AaronBertrand Діапазон тут досить малий, але будь-яке посилання на альтернативи? Для моєї цікавості.
Михай

1
Так, тут , буває, невеликий діапазон. Проблема полягає в тому, що люди засвоюють цей підхід, а потім застосовують його у набагато більших масштабах, де це стає проблемою. Навіщо використовувати повільний підхід лише тому, що в цьому випадку це "нормально"? Дивіться мою відповідь.
Аарон Бертран
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.