Skip to main content

Advanced Queries & Joins

Group data

GROUP BY WITH WHERE

Mục đích của GROUP BY là nhóm các bản ghi có cùng giá trị của một hoặc nhiều cột. Khi kết hợp với WHERE, GROUP BY sẽ nhóm các bản ghi thỏa mãn điều kiện của WHERE.

SELECT
[col1], [col2], ...
FROM
[table_name]
WHERE
[condition]
GROUP BY
[col1], [col2], ...

GROUP BY WITH AGGREGATE FUNCTIONS

Khi kết hợp với các hàm tổng hợp như COUNT, SUM, AVG, MIN, MAX, GROUP BY sẽ nhóm các bản ghi có cùng giá trị của một hoặc nhiều cột và tính toán các hàm tổng hợp trên các nhóm này.

COUNT

Dùng để đếm số lượng bản ghi trong một nhóm.

Đếm số lượng sản phẩm theo từng giá
SELECT
Price, COUNT(Id) AS 'NumberOfProducts'
FROM
Products
GROUP BY
Price

SUM

Dùng để tính tổng các giá trị trong một cột.

Tính tổng số lượng tồn kho theo từng nhóm CategoryId
SELECT
CategoryId, SUM(Stock) AS 'TotalStock'
FROM
Products
GROUP BY
CategoryId

MIN

Dùng để lấy giá trị nhỏ nhất của các giá trị trong một cột.

Hiển thị sản phẩm có giá thấp nhất theo từng nhóm CategoryId
SELECT
CategoryId, MIN(Price) AS 'MinPrice'
FROM
Products
GROUP BY
CategoryId

MAX

Dùng để lấy giá trị lớn nhất của các giá trị trong một cột.

Hiển thị sản phẩm có giá cao nhất theo từng nhóm CategoryId
SELECT
CategoryId, MAX(Price) AS 'MinPrice'
FROM
Products
GROUP BY
CategoryId

AVG

Dùng để tính giá trung bình của các giá trị trong một cột.

Tính giá trung bình theo từng nhóm CategoryId
SELECT
CategoryId, AVG(Price) AS 'AvgPrice'
FROM
Products
GROUP BY
CategoryId

CUBE và ROLLUP

ROLLUP tạo các mức tóm tắt theo danh sách GROUP BY, trong khi CUBE tạo ra tất cả các tổ hợp của các trường trong danh sách GROUP BY. Dựa trên yêu cầu của bạn, bạn có thể sử dụng ROLLUP hoặc CUBE để tạo các báo cáo tóm tắt dữ liệu phù hợp với nhu cầu của mình.

SELECT
CategoryId, SupplierId,
MIN(Price) AS 'MinPrice',
MAX(Price) AS 'MaxPrice',
AVG(Price) AS 'AvgPrice',
COUNT(*) AS 'NumProducts'
FROM
Products
GROUP BY CategoryId , SupplierId WITH CUBE
SELECT
CategoryId, SupplierId,
MIN(Price) AS 'MinPrice',
MAX(Price) AS 'MaxPrice',
AVG(Price) AS 'AvgPrice',
COUNT(*) AS 'NumProducts'
FROM
Products
GROUP BY SupplierId, CategoryId WITH ROLLUP
SELECT
CategoryId, SupplierId,
MIN(Price) AS 'MinPrice',
MAX(Price) AS 'MaxPrice',
AVG(Price) AS 'AvgPrice',
COUNT(*) AS 'NumProducts'
FROM
Products
GROUP BY CategoryId, SupplierId WITH ROLLUP

Subqueries

Subquery là một câu lệnh SELECT được sử dụng như một phần của câu lệnh SELECT khác.

Lấy danh sách các sản phẩm cùng với số lượng sản phẩm trong từng nhóm CategoryId
SELECT
C.*, (SELECT COUNT(Id) FROM Products AS P WHERE P.CategoryId = C.Id) AS 'NumberOfProducts'
FROM Categories AS C

Joins

INNER JOIN / JOIN

INNER JOIN là một phép nối dữ liệu giữa 2 bảng dữ liệu. Kết quả của phép nối này là các bản ghi có giá trị của cột join bằng nhau. Có thể dùng từ khóa JOIN thay cho INNER JOIN.

Lấy danh sách các sản phẩm cùng với tên nhà cung cấp
SELECT
P.*, S.Name AS 'SupplierName'
FROM
Products AS P INNER JOIN Suppliers AS S ON P.SupplierId = S.Id

OUTER JOIN

LEFT JOIN

LEFT JOIN là một phép nối dữ liệu giữa 2 bảng dữ liệu. Kết quả của phép nối này là các bản ghi có giá trị của cột join bằng nhau và các bản ghi của bảng bên trái sẽ được hiển thị hết.

Lấy danh sách các sản phẩm cùng với số lượng được bán trong OrderDetails
SELECT
P.Id, SUM(OD.Quantity) AS 'TotalQuantity'
FROM
Products AS P LEFT JOIN OrderDetails AS OD ON P.Id = OD.ProductId
GROUP BY P.Id
ORDER BY TotalQuantity DESC

RIGHT JOIN

RIGHT JOIN là một phép nối dữ liệu giữa 2 bảng dữ liệu. Kết quả của phép nối này là các bản ghi có giá trị của cột join bằng nhau và các bản ghi của bảng bên phải sẽ được hiển thị hết.

CTE (Common Table Expression)

CTE dùng để tạo ra một bảng ảo từ một câu lệnh SELECT. CTE có thể được sử dụng như một bảng trong các câu lệnh SELECT, INSERT, UPDATEDELETE.

Cú pháp:

WITH [CTE_Name] AS (
[CTE_Query]
)
SELECT * FROM [CTE_Name]

Ví dụ:

WITH ProductsHavingHighStock  AS (
SELECT Id, Name, Price, Discount, Stock FROM Products WHERE Stock > 50
)

SELECT * FROM ProductsHavingHighStock

COMBINING DATA

UNION

Dùng để kết hợp các bản ghi của 2 hoặc nhiều câu lệnh SELECT lại với nhau. Các câu lệnh SELECT phải có cùng số lượng cột và kiểu dữ liệu tương ứng. UNION sẽ loại bỏ các bản ghi trùng lặp.

Lấy danh sách các nhân viên và khách hàng
SELECT
Id, FirstName, LastName, Email, 'EMPLOYEE' AS 'Type'
FROM
Employees
UNION
SELECT
Id, FirstName, LastName, Email, 'CUSTOMER' AS 'Type'
FROM
Customers

UNION ALL

Dùng để kết hợp các bản ghi của 2 hoặc nhiều câu lệnh SELECT lại với nhau. Các câu lệnh SELECT phải có cùng số lượng cột và kiểu dữ liệu tương ứng. UNION ALL sẽ không loại bỏ các bản ghi trùng lặp.

INTERSECT

Dùng để lấy các bản ghi chung của 2 hoặc nhiều câu lệnh SELECT. Các câu lệnh SELECT phải có cùng số lượng cột và kiểu dữ liệu tương ứng.

Lấy danh sách các nhân viên là khách hàng
SELECT
Email, PhoneNumber
FROM
Employees
INTERSECT
SELECT
Email, PhoneNumber
FROM
Customers

EXCEPT

Dùng để lấy các bản ghi của câu lệnh SELECT đầu tiên mà không có trong các câu lệnh SELECT sau. Các câu lệnh SELECT phải có cùng số lượng cột và kiểu dữ liệu tương ứng.

Lấy danh sách các nhân viên không phải là khách hàng
SELECT
Email, PhoneNumber
FROM
Employees
EXCEPT
SELECT
Email, PhoneNumber
FROM
Customers