Trong SQL Server (Transact-SQL), mệnh đề PIVOT cho phép phân tích bảng chéo (cross tabulation) chuyển dữ liệu từ bảng này sang bảng khác, tức là lấy kết quả tổng hợp rồi chuyển từ dòng thành cột.
Ví dụ tính tổng rồi chuyền hàng thành cột trong bảng dữ liệu
Cú pháp mệnh đề PIVOT
SELECT cot_dautien AS <bidanh_cot_dautien>,
[giatri_chuyen1], [giatri_chuyen2], … [giatri_chuyen_n]
FROM
(<bang_nguon>) AS <bidanh_bang_nguon>
PIVOT
(
ham_tong (<cot_tong>)
FOR <cot_chuyen>
IN ([giatri_chuyen1], [giatri_chuyen2], … [giatri_chuyen_n])
) AS <bidanh_bang_chuye
n>;
Tên biến hoặc giá trị biến
cot_dautien
Cột hoặc biểu thức sẽ thành cột đầu tiên trong bảng mới sau khi chuyển.
bidanh_cot_dautien
Tên của cột đầu tiên trong bảng mới sau khi chuyển.
giatri_chuyen1, giatri_chuyen2, … giatri_chuyen_n
Danh sách các giá trị cần chuyển.
bang_nguon
Lệnh SELECT đưa dữ liệu nguồn (dữ liệu ban đầu) vào bảng mới.
bidanh_bang_nguon
Bí danh của bang_nguon
ham_tong
Hàm tính tổng như SUM, COUNT, MIN, MAX hay AVG.
cot_tong
Cột hoặc biểu thức được dùng với ham_tong.
cot_chuyen
Cột chứa giá trị cần chuyển.
bidanh_bang_chuyen
Bí danh của bảng sau khi chuyển.
Mệnh đề PIVOT có thể dùng trong các phiên bản sau của SQL Server: SQL Server 2014, SQL Server 2012, SQL Server 2008 R2, SQL Server 2008, SQL Server 2005.
Để thực hiện theo các bước trong hướng dẫn, hãy xem phần DDL để tạo bảng và DML để tạo dữ liệu ở cuối bài viết này rồi thử chạy trên chính cơ sở dữ liệu của bạn.
Ví dụ với mệnh đề PIVOT
Ta có bảng nhanvien với các dữ liệu như dưới đây.
so_nhanvien | ho | ten | luong | id_phong |
12009 | Nguyen | Huong | 54000 | 45 |
34974 | Pham | Hoa | 80000 | 45 |
34987 | Phan | Lan | 42000 | 45 |
45001 | Tran | Hua | 57500 | 30 |
75623 | Vu | Hong | 65000 | 30 |
Chạy lệnh SQL dưới đây để tạo truy vấn chéo bằng mệnh đề PIVOT.
SELECT ‘TongLuong’ AS TongLuongTheoPhong,
[30], [45]
FROM
(SELECT id_phong, luong
FROM nhanvien) AS BangNguon
PIVOT
(
SUM(luong)
FOR id_phong IN ([30], [45])
) AS BangChuyen;
Kết quả trả về sẽ như dưới đây.
TongLuongTheoPhong | 30 | 45 |
TongLuong | 122500 | 176000 |
Ví dụ trên tạo một bảng sau khi đã chuyển dữ liệu, cho biết tổng lương của phòng có ID là 30 và phòng có ID là 45. Kết quả nằm trên 1 hàng với 2 cột, mỗi cột là 1 phòng.
Xác định cụ thể cột trong bảng mới của truy vấn chéo
Trước tiên cần xác định trường thông tin nào muốn đưa vào bảng chuyển. Ở ví dụ này là TongLuong làm cột đầu tiên, sau đó là 2 cột id_phong 30 và id_phong 45.
SELECT “TongLuong’ AS TongLuongTheoPhong,
[30], [
45]
Xác định dữ liệu trong bảng nguồn
Tiếp theo là xác định lệnh SELECT sẽ trả về dữ liệu nguồn cho bảng mới.
Ở ví dụ này là id_phong và luong từ bảng nhanvien.
(SELECT id_phong, luong
FROM nhanvien) AS Ba
ngNguon
Cần chỉ ra bí danh cho truy vấn nguồn, trong ví dụ này là BangNguon.
Xác định hàm tính tổng
Hàm có thể dùng trong truy vấn chéo gồm SUM, COUNT, MIN, MAX và AVG. Ở ví dụ này là hàm tính tổng SUM.
PIVOT
(SUM(luong)
Xác định giá trị cần chuyển
Cuối cùng là giá trị cần chuyển để đưa vào kết quả. Đây sẽ là tiêu đề cột trong truy vấn chéo.
Ở ví dụ này, chúng ta chỉ cần trả về id_phòng 30 và 45. Các giá trị này sẽ là tên cột trong bảng mới. Cần nhớ là những giá trị này là danh sách có giới hạn của các giá trị id_phong và không nhất thiết phải chứa tất cả các giá trị.
FOR id_phong IN ([30], [45])
DDL/DML cho các ví dụ
Nếu có CSDL và muốn làm thử những ví dụ trong hướng dẫn dùng lệnh PIVOT trên, bạn sẽ cần có DDL/DML.
DDL – Data Definition Language là các lệnh tạo bảng (CREATE TABLE) để dùng trong ví dụ về mệnh đề PIVOT.
CREATE TABLE phong
( id_phong INT NOT NULL,
ten_phong VARCHAR(50) NOT NULL,
CONSTRAINT pk_phong PRIMARY KEY (id_phong)
) ;
CREATE TABLE nhanvien
( so_nhanvien INT NOT NULL,
ho VARCHAR(50) NOT NULL,
ten VARCHAR(50) NOT NULL,
luong INT,
id_phong INT,
CONSTRAINT pk_nhanvien PRIMARY KEY (so_nhanvien)
) ;
DML – Data Manipulation Language là các lệnh INSERT để tạo dữ liệu cần thiết cho bảng.
INSERTINTO phong
(id_phong, ten_phong)
VALUES
(30, ‘Ketoan
’);
INSERT INTOphong
(id_phong, ten_phong)
VALUES
(45, ‘Banhang’);
INSERT INTOnhanvien
(so_nhanvien, ho, ten, luong, id_phong)
VALUES
(12009, ‘Nguye
n’, ‘Huong’, 54000, 45);
INSERT INTOnhanvien
(so_nhanvien, ho, ten, luong, id_phong)
VALUES
(34974, ‘Pham’,
‘Hoa’, 80000, 45);
INSERT INTO nhanvien
(so_nhanvien, ho, ten, luong, id_phong)
VALUES
(34987, ‘Phan’, ‘La
n’, 42000, 45);
INSERTINTO nhanvien
(so_nhanvien, ho, ten, luong, id_phong)
VALUES
45001, ‘Tr
an’, ‘Hue’, 57500, 30);
INSERT INTO nhanvien
(so_nhanvien, ho, ten, luong, id_phong)
VALUES
(75623, ‘Vu’, ‘Hong’
, 65000, 30);
22 Th12 2020
22 Th12 2020
4 Th1 2021
15 Th12 2020
16 Th12 2020
22 Th12 2020