Bir sorgudan Eksik Tarihler Ekleme


9

Oluşturduğum bir sorgudan eksik tarihleri ​​nasıl ekleyebilirim? Aşağıdaki sonuç:

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

Sonucun, aşağıda gösterildiği gibi 0 değeri olan eksik tarihleri ​​olmasını istiyorum:

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

Lütfen sunucuya salt okunur erişimim olduğunu unutmayın.


sonucu almak için herhangi bir sorgu kullanıyor musunuz? veya tanımlanmış bir tarih aralığınız var mı? sorgu veya tablo ekleyebilirsiniz
vijayp

1
Bir takvim tablosu kullanın, bundan seçim yapın ve ardından tarihe göre frekanslarınıza katılın social.technet.microsoft.com/wiki/contents/articles/…
Mark Sinkinson

Ana tablodan sonuç almak için sorgu kullanıyorum.
Arvin

Eğer varsa salt okunur erişimi, ardından eklemek veya veritabanını güncellemek için gerekiyordu. Bunun yerine DBA ekibinizden size yardım etmesini isteyin.
Kin Shah

1
@Kin Bence soru, gerçek bir veritabanı tablosuna satır eklemek yerine sonuç kümesine satır eklemek istedikleri anlamına geliyor.
Mark Sinkinson

Yanıtlar:


12

İşte bir takvim tablosu (gerçekten olması gereken) kullanan bir örnek. Bu örnek sadece 2014'ü dolduruyor ancak istediğiniz kadar yıl doldurabilirsiniz ...

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;

Şimdi sorgu basit:

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 örneği

Bir takvim tablosu oluşturamıyorsanız (ve kullanışlı bir sayı tablosuna da sahip değilseniz), onu satır içine koyabilirsiniz:

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 örneği

Dizi oluşturma (tarihler, sayılar vb.) Hakkında daha fazla bilgi için şu diziye bakın:


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

VAKTİNİ BOŞA HARCAMAK

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

Özyinelemeli CTE yaklaşımı, tarih aralığı genişledikçe katlanarak daha pahalı hale gelir. Bu amaçla set türetmenin daha etkili yolları vardır.
Aaron Bertrand

@AaronBertrand Menzil burada oldukça küçük, ama alternatifler için herhangi bir bağlantı? Merakım için.
Mihai

1
Evet, burada küçük bir aralık oluyor. Sorun şu ki, insanlar bu yaklaşımı öğreniyor ve daha sonra sorun haline geldiği yerde çok daha büyük ölçeklerde uyguluyorlar. Neden bu durumda "iyi" olduğu için yavaş bir yaklaşım kullanılmalı? Cevabımı gör.
Aaron Bertrand
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.