- Sơ lược về bảng Pivot
- Xoay vòng dữ liệu bằng các công cụ (dbForge Studio cho MySQL)
- Xoay vòng dữ liệu bằng SQL
- Ví dụ dựa trên T-SQL cho SQL Server
- Ví dụ cho MySQL
- Tự động xoay vòng dữ liệu, tạo truy vấn động
Sơ lược về bảng tổng hợp
Bài viết này đề cập đến việc chuyển đổi dữ liệu bảng từ hàng thành cột. Sự biến đổi như vậy được gọi là bảng xoay vòng. Thông thường, kết quả của việc xoay vòng là một bảng tóm tắt, trong đó dữ liệu thống kê được trình bày ở dạng phù hợp hoặc cần thiết cho một báo cáo.
Bên cạnh đó, việc chuyển đổi dữ liệu như vậy có thể hữu ích nếu một cơ sở dữ liệu không được chuẩn hóa và thông tin được lưu trữ trong đó ở dạng không tối ưu. Vì vậy, khi tổ chức lại cơ sở dữ liệu và chuyển dữ liệu sang các bảng mới hoặc tạo biểu diễn dữ liệu bắt buộc, xoay dữ liệu có thể hữu ích, tức là chuyển các giá trị từ hàng sang cột kết quả.
Dưới đây là ví dụ về bảng sản phẩm cũ - ProductsOld và bảng mới - ProductsNew. Thông qua việc chuyển đổi từ hàng sang cột mà có thể dễ dàng đạt được kết quả như vậy.
Đây là một ví dụ về bảng tổng hợp.
Xoay vòng dữ liệu bằng các công cụ (dbForge Studio cho MySQL)
Có những ứng dụng có các công cụ cho phép thực hiện xoay vòng dữ liệu trong một môi trường đồ họa thuận tiện. Ví dụ:dbForge Studio cho MySQL bao gồm chức năng Pivot Tables cung cấp kết quả mong muốn chỉ trong vài bước.
Hãy xem ví dụ với một bảng đơn hàng được đơn giản hóa - PurchaseOrderHeader .
CREATE TABLE PurchaseOrderHeader (PurchaseOrderID INT (11) NOT NULL, EmployeeID INT (11) NOT NULL, VendorID INT (11) NOT NULL, PRIMARY KEY (PurchaseOrderID)); CHÈN PurchaseOrderHeader (PurchaseOrderID, EmployeeID, Nhà cung cấp (1) , 258, 1580); INSERT PurchaseOrderHeader (PurchaseOrderID, EmployeeID, VendorID) VALUES (2, 254, 1496); CHÈN PurchaseOrderHeader (PurchaseOrderID, EmployeeID, VendorID) VALUES VALUES (3, 257, 1494); CHỨNG NHẬN NHÂN VIÊN ) GIÁ TRỊ (4, 261, 1650); CHÈN PurchaseOrderHeader (PurchaseOrderID, EmployeeID, VendorID) GIÁ TRỊ (5, 251, 1654); CHÈN Người đứng đầu mua (PurchaseOrderID, EmployeeID, VendorID) GIÁ TRỊ Người mua (6, 253, 1664) , EmployeeID, VendorID) VALUES (7, 255, 1678); CHÈN PurchaseOrderHeader (PurchaseOrderID, EmployeeID, VendorID) GIÁ TRỊ (8, 256, 1616); CHÈN PurchaseOrderHeader (PurchaseOrderID, EmployeeID, VendorID) GIÁ TRỊ (9, 259, 1492); CHÈN PurchaseOrderHeader (PurchaseOrderID, CÁC GIÁ TRỊ CỦA NHÂN VIÊN, Người bán hàng) (10, 250, 1602); CHÈN GIÁ TRỊ PurchaseOrderHeader (PurchaseOrderID, EmployeeID, VendorID) (11, 258, 1540); ...
Giả sử rằng chúng ta cần thực hiện lựa chọn từ bảng và xác định số lượng đơn đặt hàng của một số nhân viên nhất định từ các nhà cung cấp cụ thể. Danh sách nhân viên cần thông tin - 250, 251, 252, 253, 254.
Chế độ xem ưu tiên cho báo cáo như sau.
Cột bên trái VendorID hiển thị ID của các nhà cung cấp; cột Emp250 , Emp251 , Emp252 , Emp253 và Emp254 hiển thị số lượng đơn đặt hàng.
Để đạt được điều này trong dbForge Studio cho MySQL, bạn cần:
- Thêm bảng làm nguồn dữ liệu cho biểu diễn 'Bảng Pivot' của tài liệu. Trong Database Explorer, nhấp chuột phải vào PurchaseOrderHeader bảng và chọn Gửi tới rồi đến Bảng tổng hợp trong menu bật lên.
- Chỉ định một cột mà các giá trị sẽ là các hàng. Kéo VendorID vào hộp "Trường thả hàng tại đây".
- Chỉ định một cột mà các giá trị sẽ là cột. Kéo ID nhân viên vào hộp "Thả các trường cột tại đây". Bạn cũng có thể đặt bộ lọc cho những nhân viên được yêu cầu (250, 251, 252, 253, 254).
- Chỉ định một cột, các giá trị của cột đó sẽ là dữ liệu. Kéo PurchaseOrderID vào hộp "Thả các mục dữ liệu vào đây".
- Trong các thuộc tính của PurchaseOrderID , chỉ định loại tổng hợp - Số lượng giá trị .
Chúng tôi nhanh chóng nhận được kết quả mà chúng tôi cần.
Xoay vòng dữ liệu bằng SQL
Tất nhiên, việc chuyển đổi dữ liệu có thể được thực hiện bằng cơ sở dữ liệu bằng cách viết một truy vấn SQL. Nhưng có một chút trở ngại, MySQL không có một tuyên bố cụ thể nào cho phép thực hiện điều này.
Ví dụ dựa trên T-SQL cho SQL Server
Ví dụ, SqlServer và Oracle có toán tử PIVOT cho phép thực hiện chuyển đổi dữ liệu như vậy. Nếu chúng tôi đã làm việc với SqlServer, truy vấn của chúng tôi sẽ giống như thế này.
SELECT VendorID, [250] AS Emp1, [251] AS Emp2, [252] AS Emp3, [253] AS Emp4, [254] AS Emp5FROM (SELECT PurchaseOrderID, EmployeeID, VendorID FROM Purchasing.PurchaseOrderHeader) pPIVOT (COUNT (PurchaseOrderID) CHO NHÂN VIÊN TRONG ([250], [251], [252], [253], [254])) NHƯ TORDER BY t.VendorID;
Ví dụ cho MySQL
Trong MySQL, chúng ta sẽ phải sử dụng phương tiện của SQL. Dữ liệu phải được nhóm theo cột nhà cung cấp - VendorID và cho từng nhân viên được yêu cầu ( EmployeeID ), bạn cần tạo một cột riêng biệt với một hàm tổng hợp.
Trong trường hợp của chúng tôi, chúng tôi cần tính toán số lượng đơn đặt hàng, vì vậy chúng tôi sẽ sử dụng hàm tổng hợp COUNT.
Trong bảng nguồn, thông tin về tất cả nhân viên được lưu trữ trong một cột ID nhân viên và chúng tôi cần tính toán số lượng đơn đặt hàng cho một nhân viên cụ thể, vì vậy chúng tôi cần dạy hàm tổng hợp của mình để chỉ xử lý một số hàng nhất định.
Hàm tổng hợp không tính đến giá trị NULL và chúng tôi sử dụng tính năng đặc biệt này cho mục đích của mình.
Bạn có thể sử dụng toán tử có điều kiện IF hoặc CASE sẽ trả về một giá trị cụ thể cho nhân viên mong muốn, nếu không sẽ chỉ trả về NULL; do đó, hàm COUNT sẽ chỉ đếm các giá trị không phải NULL.
Truy vấn kết quả như sau:
SELECT VendorID, COUNT (IF (EmployeeID =250, PurchaseOrderID, NULL)) AS Emp250, COUNT (IF (EmployeeID =251, PurchaseOrderID, NULL)) AS Emp251, COUNT (IF (EmployeeID =252, PurchaseOrderID, NULL) ) AS Emp252, COUNT (IF (EmployeeID =253, PurchaseOrderID, NULL)) AS Emp253, COUNT (IF (EmployeeID =254, PurchaseOrderID, NULL)) AS Emp254FROM PurchaseOrderHeader pWHERE p.>Hoặc thậm chí như thế này:
VendorID, COUNT (IF (EmployeeID =250, 1, NULL)) AS Emp250, COUNT (IF (EmployeeID =251, 1, NULL)) AS Emp251, COUNT (IF (EmployeeID =252, 1, NULL)) AS Emp252, COUNT (IF (EmployeeID =253, 1, NULL)) AS Emp253, COUNT (IF (EmployeeID =254, 1, NULL)) AS Emp254FROM PurchaseOrderHeader pWHERE p.E EmployeeID GIỮA 250 VÀ 254GROUP BỞI VendorID;Khi được thực thi, một kết quả quen thuộc sẽ thu được.
Tự động hóa tổng hợp dữ liệu, tạo truy vấn động
Có thể thấy, truy vấn có một sự nhất quán nhất định, tức là tất cả các cột được chuyển đổi đều được tạo theo cách tương tự và để viết truy vấn, bạn cần biết các giá trị cụ thể từ bảng. Để tạo truy vấn tổng hợp, bạn cần phải xem xét tất cả các giá trị có thể có và chỉ khi đó bạn mới nên viết truy vấn. Ngoài ra, bạn có thể chuyển nhiệm vụ này cho một máy chủ để máy chủ lấy các giá trị này và thực hiện động tác vụ thường ngày.
Hãy quay trở lại ví dụ đầu tiên, trong đó chúng ta đã hình thành bảng mới Sản phẩm mới từ ProductsOld bàn. Ở đó, giá trị của các thuộc tính bị giới hạn và chúng tôi thậm chí không thể biết tất cả các giá trị có thể có; chúng tôi chỉ có thông tin về nơi lưu trữ tên của các thuộc tính và giá trị của chúng. Đây là Thuộc tính và Giá trị các cột tương ứng.
Toàn bộ thuật toán tạo truy vấn SQL đi đến việc lấy các giá trị, từ đó các cột mới và các phần nối của các phần không thể thay đổi của truy vấn sẽ được hình thành.
SELECT GROUP_CONCAT (CONCAT ('MAX (IF (Property =' '', t.Property, '' ', Value, NULL)) AS', t.Property)) VÀO @PivotQueryFROM (CHỌN Thuộc tính TỪ NHÓM ProductOld BY Thuộc tính) t; SET @PivotQuery =CONCAT ('CHỌN ProductID,', @PivotQuery, 'TỪ NHÓM ProductOld THEO ProductID');Biến @PivotQuery sẽ lưu trữ truy vấn của chúng tôi, văn bản đã được định dạng cho rõ ràng.
SELECT ProductID, MAX (IF (Property ='Color', Value, NULL)) AS Color, MAX (IF (Property ='Name', Value, NULL)) AS Name, MAX (IF (Property ='ProductNumber) ', Value, NULL)) AS ProductNumber, MAX (IF (Property =' Size ', Value, NULL)) AS Size, MAX (IF (Property =' SizeUnitMeasureCode ', Value, NULL)) AS SizeUnitMeasureCodeFROM ProductOldGROUP BY ProductIDSau khi thực hiện nó, chúng ta sẽ nhận được kết quả mong muốn tương ứng với lược đồ của bảng ProductsNew.
Hơn nữa, truy vấn từ biến @PivotQuery có thể được thực thi trong tập lệnh bằng cách sử dụng câu lệnh MySQL EXECUTE.câu lệnh PREPARE FROM @PivotQuery; câu lệnh EXECUTE; câu lệnh DEALLOCATE PREPARE;