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.
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.
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.
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.
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.
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.
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
.
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.
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
, UPDATE
và DELETE
.
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.
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.
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.
SELECT
Email, PhoneNumber
FROM
Employees
EXCEPT
SELECT
Email, PhoneNumber
FROM
Customers