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

Tạo bảng tổng hợp động với chức năng QUOTENAME

Trong bài viết trước của tôi về toán tử pivot cơ bản, chúng ta đã biết cách sử dụng toán tử pivot để chuyển đổi hàng thành cột, dẫn đến bảng tổng hợp. Chúng tôi thấy rằng có ba bước chính để tạo bảng tổng hợp. Bước đầu tiên là chọn dữ liệu cơ sở. Bước thứ hai là chuyển đổi dữ liệu cơ sở thành một biểu thức có giá trị bảng và bước cuối cùng liên quan đến việc áp dụng toán tử tổng hợp cho dữ liệu tạm thời, dẫn đến bảng tổng hợp.

Hãy xem ví dụ bên dưới.

USE schooldb

SELECT * FROM

(SELECT 
	city,
	total_score
FROM 
	student
)
AS StudentTable
PIVOT(
	AVG(total_score)
	FOR city IN ([London],[Liverpool],[Leeds],[Manchester])
) AS StudentPivotTable

Lưu ý: Để tạo cơ sở dữ liệu và dữ liệu giả, hãy xem bài viết trước về Toán tử Pivot.

Hạn chế của Pivot Operator

Tuy nhiên, có một số hạn chế nhất định của toán tử trục. Bên trong toán tử tổng hợp, chúng ta phải chỉ định trường tổng hợp và các cột mà chúng ta muốn xoay dữ liệu của mình. Cuối cùng, chúng ta cũng phải đặt các giá trị riêng lẻ cho các tiêu đề cột mà chúng ta muốn tạo.

Nếu chúng tôi thực thi tập lệnh từ phần trước, chúng tôi sẽ nhận được kết quả sau:

[id bảng =35 /]

Tiêu đề của các cột là các giá trị riêng lẻ bên trong cột thành phố. Chúng tôi đã chỉ định các giá trị này bên trong toán tử pivot trong truy vấn của mình.

Phần tẻ nhạt nhất của việc tạo bảng tổng hợp là chỉ định các giá trị cho các tiêu đề cột theo cách thủ công. Đây là phần dễ xảy ra lỗi nhất, đặc biệt nếu dữ liệu trong nguồn dữ liệu trực tuyến của bạn thay đổi. Chúng tôi không thể chắc chắn rằng các giá trị mà chúng tôi đã chỉ định trong toán tử tổng hợp sẽ vẫn còn trong cơ sở dữ liệu cho đến khi chúng tôi tạo bảng tổng hợp này vào lần sau.

Ví dụ:trong tập lệnh của chúng tôi, chúng tôi đã chỉ định London, Liverpool, Leeds và Manchester làm giá trị cho các tiêu đề của bảng tổng hợp của chúng tôi. Các giá trị này tồn tại trong cột Сity của bảng sinh viên. Điều gì sẽ xảy ra nếu bằng cách nào đó một hoặc nhiều giá trị này bị xóa hoặc cập nhật? Trong những trường hợp như vậy, null sẽ được trả về.

Cách tiếp cận tốt hơn sẽ là tạo một truy vấn động sẽ trả về một tập hợp đầy đủ các giá trị từ cột mà bạn đang cố gắng tạo bảng tổng hợp của mình.

Tạo bảng tổng hợp động

Trong phần này, chúng ta sẽ xem cách tạo bảng tổng hợp động.

Điều này có nghĩa là chúng tôi sẽ không cần phải chỉ định thủ công các giá trị cho cột mà từ đó chúng tôi đang cố gắng tạo bảng tổng hợp của mình. Thay vào đó, chúng tôi sẽ đặt động các giá trị này. Vì mục đích này, chúng tôi sẽ sử dụng chức năng “QUOTENAME”.

Như mọi khi, hãy đảm bảo rằng bạn đã được sao lưu tốt trước khi thử nghiệm với một mã mới. Xem bài viết này về cách sao lưu cơ sở dữ liệu MS SQL nếu bạn không chắc chắn.

Hàm QUOTENAME

Chức năng “QUOTENAME” định dạng các kết quả đã chọn. Trước khi giải thích trục xoay động, bạn nên xem một ví dụ hoạt động nhanh về hàm “QUOTENAME”.

Hãy xem truy vấn sau.

USE schooldb

SELECT QUOTENAME(city)+ ','
FROM student

Theo mặc định, hàm “QUOTENAME” bao bọc các mục đã chọn bằng dấu ngoặc vuông. Đầu ra của truy vấn trên trông giống như sau:

[id bảng =36 /]

Lưu trữ tên cột trong một biến

Mặc dù chúng tôi đã bao bọc các giá trị cột bằng dấu ngoặc vuông, chúng tôi cần chỉ định các giá trị trong toán tử xoay ở định dạng sau:

“[Leeds], [Liverpool], [London], [Manchester]”

Để làm điều này, chúng tôi sẽ cần một biến.

USE schooldb

DECLARE @CityNames NVARCHAR(MAX) = ''

SELECT  @CityNames +=   QUOTENAME(city)+ ','
FROM 
(
	SELECT DISTINCT city
	FROM student
) AS CITIES

PRINT @CityNames

Trong truy vấn trên, chúng tôi đã khai báo một biến “@CityNames” và khởi tạo nó bằng một chuỗi trống. Sau đó, chúng tôi sử dụng câu lệnh SELECT để chọn các tên thành phố riêng biệt từ cột thành phố và lưu trữ chúng theo cách lặp lại trong biến “@CityNames”. Trong mỗi lần lặp lại, một giá trị riêng biệt trong cột thành phố cùng với dấu phẩy sẽ được thêm vào biến “@CityNames”.

Sau đó, chúng tôi in giá trị được lưu trữ trong biến này. Kết quả của truy vấn trên sẽ giống như sau:

“[Leeds], [Liverpool], [London], [Manchester],”

Nếu bạn nhìn vào đầu ra, có một dấu phẩy sau giá trị cuối cùng. Chúng tôi không cần điều đó.

Xóa dấu phẩy ở cuối

Để loại bỏ dấu phẩy ở cuối, chúng ta sẽ sử dụng hàm LEFT lấy một chuỗi làm đối số đầu tiên của nó. Đối số thứ hai là số ký tự được trả về từ chuỗi đó bắt đầu từ ký tự đầu tiên. Hãy xem truy vấn sau:

USE schooldb

DECLARE @CityNames NVARCHAR(MAX) = ''

SELECT  @CityNames +=   QUOTENAME(city)+ ','
FROM 
(
	SELECT DISTINCT city
	FROM student
) AS CITIES

SET @CityNames = LEFT(@CityNames, LEN(@CityNames)-1)

PRINT @CityNames

Ở đây, hãy chú ý đến dòng này của tập lệnh:

SET @CityNames = LEFT(@CityNames, LEN(@CityNames)-1)

Trong dòng script này, chúng tôi đã sử dụng hàm LEFT để lấy tất cả các ký tự ở phía bên trái của giá trị được lưu trữ trong biến “@CityNames”, bắt đầu từ phần tử đầu tiên. Trong đối số thứ hai, chúng tôi sử dụng hàm LEN để tính số phần tử giá trị được lưu trữ trong hàm “@CityNames” và cuối cùng, chúng tôi lấy nó trừ đi 1. Thao tác này sẽ xóa dấu phẩy ở cuối chuỗi khỏi chuỗi. Đầu ra sẽ như thế này:

[Leeds], [Liverpool], [London], [Manchester]

Chuyển đổi truy vấn SQL thành chuỗi

Bây giờ, hy vọng, chúng ta có thể sử dụng biến “@CityNames” bên trong toán tử trục của chúng ta như sau:

PIVOT(
	AVG(total_score)
	FOR city IN ( @CityNames )

Tuy nhiên, chúng ta không thể sử dụng một biến bên trong toán tử trục của chúng ta. Cách tiếp cận thay thế là chuyển đổi truy vấn SQL hoàn chỉnh của chúng tôi thành một chuỗi. Bên trong chuỗi này, chúng tôi sẽ nối biến “@CityNames”.

USE schooldb

DECLARE @CityNames NVARCHAR(MAX) = ''
DECLARE @Query NVARCHAR(MAX) = '' 

SELECT  @CityNames +=   QUOTENAME(city)+ ','
FROM 
(
	SELECT DISTINCT city
	FROM student
) AS CITIES

SET @CityNames = LEFT(@CityNames, LEN(@CityNames)-1)

SET @Query =
'SELECT * FROM

(SELECT 
	city,
	total_score
FROM 
	student
)
AS StudentTable
PIVOT(
	AVG(total_score)
	FOR city IN (' + @CityNames +')
) AS StudentPivotTable'

PRINT @Query

Ở đây chúng tôi đã khai báo một biến “@Query” và lưu trữ truy vấn SQL của chúng tôi trong biến này. Bên trong toán tử trục, chúng tôi đã nối giá trị được lưu trữ bên trong biến “@CityNames”. Để xem truy vấn được thực thi trông như thế nào, chúng tôi đã in giá trị của biến “@Query”. Truy vấn kết quả sẽ giống như thế này trong đầu ra:

SELECT * FROM

(SELECT 
	city,
	total_score
FROM 
	student
)
AS StudentTable
PIVOT(
	AVG(total_score)
	FOR city IN ([Leeds],[Liverpool],[London],[Manchester])
) AS StudentPivotTable

Đây chính xác là loại truy vấn mà chúng tôi muốn thực hiện. Tuy nhiên, đây là ở định dạng Chuỗi. Bước cuối cùng là thực hiện truy vấn SQL này được lưu trữ dưới dạng chuỗi văn bản. Để làm điều này, chúng tôi sẽ sử dụng SQL động.

Thực thi SQL động

Chúng tôi sử dụng thủ tục dựng sẵn “sp_executesql” để thực thi SQL động. Chúng tôi sẽ sử dụng thủ tục được lưu trữ này để thực hiện truy vấn được lưu trữ trong biến @Query. Truy vấn cuối cùng của chúng tôi để tạo bảng tổng hợp động trông giống như sau:

USE schooldb

DECLARE @CityNames NVARCHAR(MAX) = ''
DECLARE @Query NVARCHAR(MAX) = '' 

SELECT  @CityNames +=   QUOTENAME(city)+ ','
FROM 
(
	SELECT DISTINCT city
	FROM student
) AS CITIES

SET @CityNames = LEFT(@CityNames, LEN(@CityNames)-1)

SET @Query =
'SELECT * FROM

(SELECT 
	city,
	total_score
FROM 
	student
)
AS StudentTable
PIVOT(
	AVG(total_score)
	FOR city IN (' + @CityNames +')
) AS StudentPivotTable'

EXECUTE sp_executesql @Query

Khi thực hiện truy vấn trên, bạn sẽ thấy kết quả sau:

[id bảng =37 /]

Tuy nhiên, lần này, chúng tôi không chỉ định thủ công các giá trị cho các tiêu đề của bảng tổng hợp. Thay vào đó, các tiêu đề đã được tính toán động dẫn đến một bảng tổng hợp độ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. Thủ tục lưu trữ để lấy thông tin lưu trữ máy chủ trong máy chủ

  2. Aqua Data Studio

  3. Hợp nhất các tệp dữ liệu với Statistica, Phần 1

  4. Cách tạo chỉ mục trong Django mà không có thời gian ngừng hoạt động

  5. SQL DROP COLUMN dành cho người mới bắt đầu