Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Điền vào ngày bị thiếu cho đầu ra truy vấn máy chủ SQL bằng CTE

Tuần trước, một đồng nghiệp của tôi đã yêu cầu tôi giúp anh ta viết một truy vấn để điền vào những ngày còn thiếu trong kết quả truy vấn. Tôi đã xem qua một số giải pháp, dường như không thuận tiện cho tôi. Vì vậy, tôi đã biên dịch của riêng mình bằng cách sử dụng CTE đệ quy hoặc Biểu thức bảng chung.

Tuyên bố sự cố

Giả sử chúng ta có một bảng chứa các bản ghi cuộc gọi đến của bộ phận chăm sóc khách hàng từ ngày 1 đến ngày 10 tháng 6 năm 2021. Trong một số ngày, không có bản ghi cuộc gọi nào. Nếu chúng tôi chạy câu lệnh GROUP BY trên cột datetime, một số ngày sẽ bị thiếu. Đầu ra mong muốn là, ngày bị thiếu sẽ là giá trị 0. Đầu ra mẫu sẽ ở bên dưới:

Truy vấn

SELECT CONVERT(varchar(10),B.call_time,111) AS OriginalDate, COUNT(*) as total
FROM Test1 B
GROUP BY CONVERT(varchar(10),B.call_time,111)
ORDER BY CONVERT(varchar(10),B.call_time,111)

Đầu ra mẫu

Đầu ra mong muốn

Phương pháp tiếp cận giải pháp của tôi

Thay vì sử dụng truy vấn GROUP BY đơn giản, CTE và SUB QUERY được sử dụng. CTE đệ quy được sử dụng để tạo phạm vi ngày và LEFT OUTER JOIN được sử dụng để kết hợp giá trị với ngày. Hãy giải thích từng bước.

CTE / Biểu thức bảng chung

CTE hoặc Biểu thức bảng chung chỉ định một tập kết quả được đặt tên tạm thời được lấy từ một truy vấn đơn giản và được xác định trong phạm vi thực thi của một câu lệnh SELECT / INSERT / UPDATE / DELETE / MERGE / CREATE VIEW. Nó có thể tham chiếu đến chính nó cũng được gọi là CTE đệ quy.

Chuẩn bị dữ liệu

-- Create the table
CREATE TABLE Test1(
call_time datetime,
name    varchar(10) default ('Mehedi')
)
GO
-- Populate with sample data
INSERT INTO Test1 (call_time, name)
VALUES ('2021-06-01 08:00','A')
,('2021-06-01 09:05','C')
,('2021-06-01 12:50','E')
,('2021-06-01 16:17','D')
,('2021-06-01 18:53','G')
,('2021-06-03 11:07','F')
,('2021-06-03 13:09','A')
,('2021-06-03 16:26','E')
,('2021-06-03 19:56','C')
,('2021-06-03 21:24','A')
,('2021-06-04 19:13','A')
,('2021-06-04 11:45','B')
,('2021-06-04 15:02','C')
,('2021-06-08 23:02','A')
,('2021-06-09 03:04','E')

Xây dựng truy vấn

Đầu tiên, chúng tôi sẽ viết một CTE sẽ tạo ra tất cả các ngày trong phạm vi ngày.

DECLARE @StartDate DATE, @EndDate DATE
SET @StartDate = '2021-11-01'
SET @EndDate = '2021-11-08'
;WITH cte AS
(    SELECT @StartDate AS sDate
UNION ALL
SELECT DATEADD(DAY,1,sDate)
FROM cte
WHERE sDate < @EndDate
)
SELECT  sDate
FROM cte;

Bây giờ CTE này sẽ được cấu trúc lại để tạo một truy vấn phụ với LEFT OUTER JOIN để ngày không có giá trị xuất hiện và chứa giá trị 0.

DECLARE @startdate DATETIME = '2021-06-01'
DECLARE @endDate DATETIME = '2021-06-10'
;WITH cte
AS
(
SELECT @startdate as sDate
UNION All
SELECT DATEADD(day,1,sDate) From cte where DATEADD(day,1,sDate) <= @endDate
)
SELECT
C.OriginalDate
,C.total
FROM
(
SELECT CONVERT(varchar(10),A.sDate,111) AS OriginalDate, COUNT(B.call_time) as total
FROM cte A
LEFT OUTER JOIN Test1 B
ON A.sDate = CONVERT(varchar(10),B.call_time,111)
GROUP by CONVERT(varchar(10),A.sDate,111)
) C
ORDER BY C.OriginalDate

Đầu ra cuối cùng

Kết luận

Hy vọng, nó sẽ hữu ích cho bạn. Chúc bạn TSQLing vui vẻ!

Nó cũng có sẵn trong blog cá nhân của tôi!


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Làm cách nào để kiểm tra xem một chuỗi có phải là mã định danh duy nhất hay không?

  2. Cách liệt kê tất cả các ngày giữa hai ngày

  3. Cách nhận các giá trị Tối đa và Tối thiểu từ một Bảng bằng cách sử dụng Hàm Tổng hợp - Hướng dẫn SQL Server / TSQL Phần 129

  4. Khám phá SQL Server 2014 CHỌN VÀO song song

  5. trường đếm to_sql pyodbc không chính xác hoặc lỗi cú pháp