Masukkan Tanggal Tidak Ada dari kueri

9

Bagaimana saya bisa memasukkan tanggal yang hilang dari kueri yang saya buat. Hasilnya di bawah ini:

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

Saya ingin hasilnya kehilangan tanggal dengan nilai 0 seperti yang ditunjukkan di bawah ini:

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

Harap dicatat bahwa saya hanya membaca akses ke server.

Arvin
sumber
apakah Anda menggunakan pertanyaan apa pun untuk mengambil hasilnya? atau apakah Anda memiliki rentang tanggal yang ditentukan. dapatkah Anda menambahkan kueri atau tabel Anda
vijayp
1
Menggunakan tabel kalender, pilih dari itu dan kemudian bergabung ke frekuensi Anda berdasarkan tanggal social.technet.microsoft.com/wiki/contents/articles/...
Mark Sinkinson
Saya menggunakan kueri untuk mengambil hasil dari tabel utama.
Arvin
Jika Anda hanya memiliki akses baca , maka Anda tidak seharusnya memasukkan atau memperbarui basis data. Alih-alih minta tim DBA Anda untuk membantu Anda.
Kin Shah
1
@Kin Saya pikir pertanyaannya berarti mereka ingin menyisipkan baris ke dalam set hasil, daripada memasukkan baris ke dalam tabel database aktual.
Mark Sinkinson

Jawaban:

12

Berikut adalah contoh menggunakan tabel kalender (yang seharusnya Anda miliki). Contoh ini hanya memuat 2014 tetapi Anda dapat mengisinya dengan sebanyak yang Anda suka ...

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;

Sekarang pertanyaannya sederhana:

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);

Contoh SQLfiddle

Jika Anda tidak dapat membuat tabel kalender (dan juga tidak memiliki tabel angka), maka Anda cukup memasukkannya:

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);

Contoh SQLfiddle

Untuk lebih lanjut tentang menghasilkan set (tanggal, angka, dll) lihat seri ini:

Aaron Bertrand
sumber
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

BIOLA

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
Mihai
sumber
Pendekatan CTE rekursif menjadi lebih mahal secara eksponensial karena rentang tanggal semakin luas. Ada cara yang lebih efisien untuk mendapatkan perangkat untuk tujuan ini.
Aaron Bertrand
@ AaronBertrand Kisarannya cukup kecil di sini, tetapi ada tautan ke alternatif? Untuk keingintahuan saya.
Mihai
1
Ya, di sini , itu terjadi menjadi rentang kecil. Masalahnya adalah orang mempelajari pendekatan ini dan kemudian menerapkannya dalam skala yang jauh lebih besar di mana itu menjadi masalah. Mengapa menggunakan pendekatan lambat hanya karena itu "ok" dalam kasus ini? Lihat jawaban saya.
Aaron Bertrand