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

Truy vấn SQL Server:hàng tạo cột (Xoay vòng?)

Pivoting cũng giống như chia nhóm. Bạn có thể xem nó như một nhóm giới hạn với một "hiệu ứng đặc biệt". Hạn chế bao gồm thực tế là chỉ có thể có một cột tổng hợp. (Trong truy vấn GROUP BY thông thường, bạn có thể có nhiều hơn một, đương nhiên.) Và tất nhiên, bởi 'hiệu ứng đặc biệt', ý tôi là một trong các cột khác (và, chỉ một) được chuyển đổi thành nhiều cột.

Hãy lấy truy vấn GROUP BY của bạn làm ví dụ. Bạn có ba cột trong đầu ra. Một trong số chúng, Count , là cột chứa thông tin tổng hợp. Đó là cái sẽ nằm rải rác giữa nhiều cột trong một truy vấn PIVOT. Một cột khác, Priority , là một trong hai cột khác mà kết quả được nhóm theo và cũng là cột cần được xoay. Cuối cùng, EntryDate là cột GROUP BY khác. Nó chỉ nên giữ nguyên như hiện tại, vì nó không trực tiếp tham gia vào việc xoay vòng.

Bây giờ, hãy xem cách SELECT chính của bạn được chuyển đổi từ truy vấn GROUP BY thông thường thành truy vấn PIVOT theo từng bước:

  1. Vì nhóm được ngụ ý trong một truy vấn PIVOT, mệnh đề GROUP BY bị loại bỏ. Thay vào đó, một mệnh đề PIVOT được giới thiệu.

  2. Count biểu thức của cột được chuyển từ mệnh đề SELECT sang mệnh đề PIVOT.

  3. Việc tách Priority được xác định trong mệnh đề PIVOT.

  4. PriorityCount các cột trong mệnh đề CHỌN được thay thế bằng danh sách các cột được xác định trong mệnh đề PIVOT.

  5. EntryDate không thay đổi trong mệnh đề SELECT.

Và đây là truy vấn kết quả, với các nhận xét đánh dấu mọi phần của quá trình chuyển đổi được mô tả ở trên:

WITH TATH(Priority, EntryDate) AS 
(
    SELECT TH.Priority as Priority, DATEADD(dd, 0, DATEDIFF(dd, 0, entryDate)) as EntryDate
      FROM TicketAssignment TA, TicketHeader TH 
     WHERE TA.TicketID = TH.TicketID   
       AND TA.Company = 'IT'
       AND TA.CurrentRole IN ('SA1B','SA1C','SDA')
) 
SELECT
  convert(varchar(10), EntryDate,103) as EntryDate,                       -- #5
  [0] AS Priority0, [1] AS Priority1, [2] AS Priority2, [3] AS Priority3  -- #4
FROM TATH
PIVOT (                                                                   -- #1
  COUNT(*)                                                                -- #2
  FOR Priority IN ([0], [1], [2], [3])                                    -- #3
) p

/*  -- your original main query, for comparison
SELECT
  Priority,                                                               -- #4
  convert(varchar(10),                                                    -- #5
  EntryDate,103) as EntryDate, COUNT(*) AS Count                          -- ##2&4
FROM TATH 
GROUP BY Priority, EntryDate                                              -- #1
*/

Có một ghi chú bổ sung trên danh sách cột trong mệnh đề PIVOT. Trước hết, bạn phải hiểu rằng tập hợp kết quả của một truy vấn SQL được cho là cố định về số lượng cột và tên của chúng. Điều đó có nghĩa là bạn phải liệt kê rõ ràng tất cả các cột đã chuyển đổi mà bạn muốn xem trong đầu ra. Các tên được lấy từ các giá trị của cột đang được xoay vòng nhưng chúng phải được chỉ định là tên , không phải là giá trị. Đó là lý do tại sao bạn có thể thấy dấu ngoặc vuông xung quanh các số được liệt kê. Vì bản thân các số không thỏa mãn quy tắc cho số nhận dạng thông thường , chúng phải được phân tách.

Bạn cũng có thể thấy rằng bạn có thể đặt bí danh cho các cột xoay quanh trong mệnh đề SELECT giống như bất kỳ cột hoặc biểu thức nào khác. Vì vậy, cuối cùng, bạn không phải kết thúc với 0 vô nghĩa , 1 v.v ... định danh và thay vào đó, bạn có thể gán các cột đó bằng bất kỳ tên nào bạn thích.

Nếu bạn muốn số lượng và / hoặc tên của các cột xoay quanh là động, bạn sẽ phải tạo truy vấn động, tức là trước tiên thu thập các tên, sau đó kết hợp chúng thành một chuỗi chứa phần còn lại của truy vấn và gọi truy vấn cuối cùng với EXEC () hoặc EXEC sp_executesql . Bạn có thể tìm kiếm trang web này để biết thêm thông tin về xoay vòng động.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Ngăn chặn SQL Injection trong mệnh đề ORDER BY

  2. T-SQL:phân tách và tổng hợp các giá trị được phân tách bằng dấu phẩy

  3. Sử dụng TYPE_ID () để lấy ID của một loại dữ liệu trong SQL Server

  4. AT TIME ZONE - một tính năng mới được yêu thích trong SQL Server 2016

  5. Truy vấn đệ quy SQL Server