Advanced SQL Queries

sql_queries.jpg

Sau đây, tôi sẽ giới thiệu cho bạn đọc một số câu lệnh SQL nâng cao mà có thể các bạn ít khi hoặc chưa dùng tới, nhưng sẽ rất là hữu ích ^^. Cùng tìm hiểu xem những câu lệnh đó như thế nào nha 😉

SQL UNION

Mệnh đề/Toán tử UNION trong SQL được sử dụng để kết hợp kết quả của hai hoặc nhiều lệnh SELECT mà không trả về bất cứ bản sao nào của bản ghi. (tương tự nhiên lệnh JOIN kết hợp với SELECT DISTINCT)

Để sử dụng UNION, mỗi lệnh SELECT phải có cùng số cột đã chọn, cùng số biểu thức của các cột, cùng kiểu dữ liệu, và chúng có cùng thứ tự, nhưng chúng không cần phải có cùng độ dài.

Cú pháp của mệnh đề này như sau:

[SQL Statement 1]
UNION
[SQL Statement 2];

Một ví dụ sau đây, chúng ta có 2 bảng:

Bảng Store_Information

Store_Name Sales Date
Ha Noi 500 15-04-2016
Vinh 1000 15-04-2016
Hue 700 21-04-2016
Da Nang 600 22-04-2016

Bảng Internet_Sales

Date Sales
16-04-2016 200
20-04-2016 300
21-04-2016 600

Để tìm kiếm tất cả những ngày giao dịch sản phẩm, ta sử dụng query sau:

SELECT Date from Store_Information
UNION
SELECT Date from Internet_Sales;

Kết quả sẽ như sau:

Date
15-04-2016
16-04-2016
20-04-2016
21-04-2016
22-04-2016

SQL UNION ALL

Toán tử UNION ALL được sử dụng để kết hợp nhiều kết quả của hai hoặc nhiều lệnh SELECT bao gồm cả các bản sao của các hàng.

Các qui tắc áp dụng cho UNION cũng áp dụng cho toán tử UNION ALL.

Cú pháp của mệnh đề này như sau:

[SQL Statement 1]
UNION ALL
[SQL Statement 2];

Áp dụng đối với 2 bảng ở trên, ta có query tương tự:

SELECT Date from Store_Information
UNION ALL
SELECT Date from Internet_Sales;

Khi đó, ta được kết quả như sau:

Date
15-04-2016
15-04-2016
21-04-2016
22-04-2016
16-04-2016
20-04-2016
21-04-2016

Điểm khác biệt duy nhất giữa UNIONUNION ALLUNION chỉ lựa chọn những giá trị khác biệt nhau, còn UNION ALL thì lựa chọn tất cả các giá trị.

SQL INTERSECT

Tương tự như lệnh UNION, INTERSECT cũng hoạt động dựa trên 2 câu lệnh SQL. Có điều khác là trong khi UNION chủ yếu hoạt động như một OR operator (giá trị được chọn nếu xuất hiện trong câu lệnh 1 hoặc 2) thì INTERSECT hoạt động như một AND operator (giá trị chỉ được chọn nếu xuất hiện trong cả 2 câu lệnh).

Cú pháp của nó như sau:

[SQL Statement 1]
INTERSECT
[SQL Statement 2];

Áp dụng tương tự đối với 2 bảng ở trên, ta được query như sau:

SELECT Date from Store_Information
INTERSECT
SELECT Date from Internet_Sales;

Và kết quả sẽ được như sau:

Date
21-04-2016

Chú ý rằng, INTERSECT chỉ trả về những giá trị khác biệt nhau 😉

SQL MINUS

Lệnh MINUS thực hiện trên 2 câu lệnh SQL. Nó sẽ lấy tất cả giá trị trả về từ câu SQL thứ nhất, sau đó loại trừ những kết quả xuất hiện trong câu SQL thứ 2 để trả về kết quả cuối cùng.

Cú pháp của nó như sau:

[SQL Statement 1]
MINUS
[SQL Statement 2];

Tiếp tục sử dụng 2 bảng đã tạo ở trên, ta có câu query tương tự:

SELECT Date from Store_Information
MINUS
SELECT Date from Internet_Sales;

Và kết quả trả về sẽ được như sau:

Date
15-04-2016
22-04-2016

Chú ý rằng, MINUS cũng sẽ chỉ trả về những giá trị khác biệt nhau

Một vài cơ sở dữ liệu có thể sử dụng EXCEPT thay cho MINUS. Hãy kiểm tra kĩ tài liệu về cơ sở dữ liệu của bạn để có thể sử dụng sao cho đúng 😃

SQL VIEW

Một View là không gì khác ngoài môt lệnh SQL mà được lưu giữ trong Database với một tên liên kết. Một view có thể chứa tất cả các hàng của một bảng hoặc các hàng đã được chọn từ một bảng. Một view có thể được tạo từ một hoặc nhiều bảng, phụ thuộc vào truy vấn SQL đã viết để tạo một view.

View, về bản chất giống các Virtual Table (bảng ảo), cho phép người dùng thực hiện:

  • Cấu trúc dữ liệu theo cách mà người dùng tìm thấy tính tự nhiên hoặc tính trực quan.

  • Giới hạn truy cập tới dữ liệu để mà một người dùng có thể thấy và (đôi khi) sửa đổi một cách chính xác nhưng gì họ cần.

  • Tổng kết dữ liệu từ các bảng đa dạng để tạo các bản báo cáo.

Cú pháp để tạo một View như sau:

CREATE VIEW "VIEW_NAME" AS "SQL Statement";

Hãy nhìn vào một ví dụ sau đây để hiểu rõ hơn nhé. Ta có bảng Students sau đây:

|ID|NAME|AGE|ADDRESS|CLASS| |---|---|---|---| |1|Hung|22|Ha Noi|D10CN6| |2|Kien|23|Hai Phong|D09CN2| |3|Tung|21|Ha Noi|D11VT2| |4|Nam|22|Nghe An|D10KT1| |5|Quang|23|Phu Tho|D09VT3|

Bây giờ, chúng ta sẽ tạo một View của bảng đó bao gồm trường NameAge như sau:

CREATE VIEW Students_View AS
SELECT NAME, AGE
FROM Students;

Bây giờ, bạn đã có thể truy vấn đến bảng Students_View như một bảng thực sự như sau:

SELECT * FROM Students_View;

Kết quả sẽ được như sau:

NAME AGE
Hung 22
Kien 23
Tung 21
Nam 22
Quang 23

SQL Subquery

Subquery (còn được gọi truy vấn phụ hay truy vấn lồng nhau) là một truy vấn bên trong truy vấn SQL khác và được nhúng bên trong mệnh đề WHERE.

Một truy vấn con được sử dụng để trả về dữ liệu mà sẽ được sử dụng trong truy vấn chính như là một điều kiện để thu hẹp dữ liệu được thu nhận.

Cú pháp của một Subquery như sau:

SELECT "column_name1"
FROM "table_name1"
WHERE "column_name2" [Comparison Operator]
(SELECT "column_name3"
FROM "table_name2"
WHERE "condition");

Hãy sử dụng 2 bảng sau đây để minh họa cho ý tưởng về Subquery:

Bảng Store_Information

Store_Name Sales Date
Ha Noi 500 15-04-2016
Hai Phong 1000 15-04-2016
Dong Thap 700 21-04-2016
Can Tho 600 22-04-2016

Bảng Geography

Region_Name Store_Name
North Ha Noi
North Hai Phong
South Dong Thap
South Can Tho

Chúng ta muốn sử dụng Subquery để tính tổng doanh thu của tất cả các cửa hàng ở miền Bắc, hãy sử dụng câu lệnh sau:

SELECT SUM(Sales) FROM Store_Information
WHERE Store_Name IN
(SELECT Store_Name FROM Geography
WHERE Region_Name = 'North');

Khi đó, ta sẽ thu được kết quả như sau:

SUM(Sales)
1500

SQL CASE

CASE cung cấp câu truy vấn sử dụng điều kiện if-then-else cho SQL. Có hai kiểu:

  • biểu thức Simple CASE - so sánh một biểu thức với một giá trị tĩnh
  • biểu thức Searched CASE - so sánh một biểu thức với một hoặc nhiều điều kiện logic

Simple CASE

Cú pháp như sau:

SELECT CASE ("column_name")
  WHEN "value1" THEN "result1"
  WHEN "value2" THEN "result2"
  ...
  [ELSE "resultN"]
  END
FROM "table_name";

Áp dụng với bảng Store_Information sau đây:

Store_Name Sales Date
Ha Noi 800 15-04-2016
Hai Phong 1000 15-04-2016
Dong Thap 400 21-04-2016
Can Tho 450 22-04-2016

Ví dụ nếu chúng ta muốn nhân doanh thu của 'Ha Noi' lên 3, doanh thu của 'Hai Phong' lên 2, và giữ nguyên doanh thu của các nơi còn lại, chúng ta có thể sử dụng câu truy vấn sau;

SELECT Store_Name, CASE Store_Name
  WHEN 'Ha Noi' THEN Sales * 3
  WHEN 'Hai Phong' THEN Sales * 2
  ELSE Sales
  END
"New Sales",
Date
FROM Store_Information;

Ta sẽ thu được kết quả như sau:

Store_Name New Sales Date
Ha Noi 2400 15-04-2016
Hai Phong 2000 15-04-2016
Dong Thap 400 21-04-2016
Can Tho 450 22-04-2016

Searched CASE

Cú pháp như sau:

SELECT CASE
  WHEN "condition1" THEN "result1"
  WHEN "condition2" THEN "result2"
  ...
  [ELSE "resultN"]
  END
FROM "table_name";

Nếu bạn muốn định nghĩa trạng thái doanh thu của các cửa hàng dựa trên luật như sau:

  • Nếu Sales >= 1,000, sẽ là "Good Day"
  • Nếu Sales >= 500 and < 1,000, sẽ là "OK Day"
  • Còn nếu Sales < 500, sẽ là "Bad Day"

Chúng ta có thể sử dụng câu lệnh như sau:

SELECT Store_Name, Date, CASE
  WHEN Sales >= 1000 THEN 'Good Day'
  WHEN Sales >= 500 THEN 'OK Day'
  ELSE 'Bad Day'
  END
"Sales Status"
FROM Store_Information;

Khi đó, ta sẽ thu được kết quả như sau:

Store_Name Date Sales Status
Ha Noi 15-04-2016 OK Day
Hai Phong 15-04-2016 Good Day
Dong Thap 21-04-2016 Bad Day
Can Tho 22-04-2016 Bad Day

Chú ý rằng, Simple CASE là một trường hợp đặc biệt của Searched CASE

Hi vọng, một số câu lệnh SQL nâng cao đã trình bày ở phía trên sẽ giúp ích cho bạn đọc ^_^

Tài liệu tham khảo

  1. https://www.1keydata.com/sql/advanced.html
  2. https://technet.microsoft.com/en-us/library/aa213245(v=sql.80).aspx