Chèn ngày thiếu từ một truy vấn


9

Làm thế nào tôi có thể chèn ngày bị thiếu từ một truy vấn tôi đã tạo. Kết quả dưới đây:

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

Tôi muốn kết quả bị thiếu ngày với giá trị 0 như dưới đây:

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

Xin lưu ý rằng tôi chỉ đọc quyền truy cập vào máy chủ.


bạn đang sử dụng bất kỳ truy vấn để lấy kết quả? hoặc bạn có một phạm vi ngày được xác định. bạn có thể thêm truy vấn hoặc bảng của mình không
vijayp

1
Sử dụng bảng lịch, chọn từ đó và sau đó tham gia vào tần số của bạn theo ngày social.technet.microsoft.com/wiki/contents/articles/ Kẻ
Mark Sinkinson

Tôi đang sử dụng truy vấn để lấy kết quả từ bảng chính.
Arvin

Nếu bạn chỉ có quyền truy cập đọc , thì bạn không cần phải chèn hoặc cập nhật cơ sở dữ liệu. Thay vào đó hãy yêu cầu nhóm DBA của bạn giúp bạn.
Kin Shah

1
@Kin Tôi nghĩ rằng câu hỏi có nghĩa là họ muốn chèn các hàng vào tập kết quả, thay vì chèn các hàng vào bảng cơ sở dữ liệu thực tế.
Mark Sinkinson

Câu trả lời:


12

Dưới đây là một ví dụ sử dụng bảng lịch (mà bạn thực sự nên có). Ví dụ này chỉ xuất hiện trong năm 2014 nhưng bạn có thể đưa nó vào bao nhiêu năm tùy thích ...

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;

Bây giờ truy vấn rất đơn giản:

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

Ví dụ SQLfiddle

Nếu bạn không thể tạo bảng lịch (và cũng không có bảng số tiện dụng), thì bạn có thể đặt bảng nội tuyến:

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

Ví dụ SQLfiddle

Để biết thêm về cách tạo bộ (ngày, số, v.v.) hãy xem loạt bài này:


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

VĨ CẦM

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

Phương pháp CTE đệ quy trở nên đắt hơn theo cấp số nhân khi phạm vi ngày trở nên rộng hơn. Có nhiều cách hiệu quả hơn để lấy được bộ cho mục đích này.
Aaron Bertrand

@AaronBertrand Phạm vi khá nhỏ ở đây, nhưng có liên kết nào đến các lựa chọn thay thế không? Vì sự tò mò của tôi.
Mihai

1
Vâng, ở đây , nó là một phạm vi nhỏ. Vấn đề là mọi người tìm hiểu phương pháp này và sau đó áp dụng nó ở quy mô lớn hơn nhiều, nơi nó trở thành một vấn đề. Tại sao sử dụng một cách tiếp cận chậm chỉ vì nó "ok" trong trường hợp này? Xem câu trả lời của tôi.
Aaron Bertrand
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.