Truy vấn SQL nâng cao trong PostgreSQL

Truy vấn SQL nâng cao trong PostgreSQL không chỉ dừng lại ở việc lấy dữ liệu từ cơ sở dữ liệu mà còn cho phép người dùng phân tích, tổng hợp và khai thác thông tin phục vụ cho báo cáo và ra quyết định. Trong thực tế, dữ liệu thường cần được thống kê, gom nhóm và phân tích theo nhiều góc nhìn khác nhau để hỗ trợ quá trình đánh giá hoạt động kinh doanh hoặc nghiên cứu dữ liệu.

Trong PostgreSQL, việc thực hiện truy vấn SQL nâng cao thường dựa trên một số kỹ thuật quan trọng như sử dụng các hàm thống kê (Aggregate Functions) để tính toán dữ liệu, GROUP BY để gom nhóm các bản ghi theo từng tiêu chí và HAVING để lọc các nhóm dữ liệu sau khi đã thực hiện thống kê. Những công cụ này giúp chuyển đổi dữ liệu thô thành thông tin có ý nghĩa, hỗ trợ hiệu quả cho việc phân tích dữ liệu và xây dựng các báo cáo tổng hợp.

Việc hiểu và sử dụng thành thạo truy vấn SQL nâng cao trong PostgreSQL là nền tảng quan trọng đối với các nhà phân tích dữ liệu, lập trình viên và những người làm việc với hệ thống cơ sở dữ liệu trong thực tế.

Truy vấn SQL nâng cao trong PostgreSQL

1. Các hàm thống kê: nền tảng của phân tích dữ liệu

1.1. COUNT – Đếm dữ liệu (đếm dòng / đếm giá trị)

COUNT dùng để đếm dữ liệu trong bảng.

COUNT(*)COUNT(*) đếm tất cả các dòng trong bảng.
COUNT(column)đếm các giá trị khác NULL trong cột.
COUNT(DISTINCT column)Đếm giá trị khác nhautrong cột.

Ứng dụng của COUNT:

  • Đếm tổng số khách hàng, đơn hàng, sản phẩm
  • Đếm số lượng bản ghi thỏa mãn điều kiện
  • Kiểm tra dữ liệu rỗng

Ví dụ: bảng customers

Đếm tổng số khách hàng với câu lệnh:

SELECT COUNT(*) AS total_customers
FROM customers;

Kết quả có ngay:


Ví dụ: bảng orders

Đếm số đơn hàng của mỗi khách hàng

SELECT customer_id, COUNT(*) AS order_count
FROM orders
GROUP BY customer_id;

Chúng ta có kết quả:


Một ví dụ: bảng employees

  • Đếm số dòng dữ liệu trong bảng employees:
SELECT COUNT(*) FROM employees;  -- ==> 10
  • Tinh (đếm) các giá trị KHÔNG NULL trong cột phone
SELECT COUNT(phone) FROM employees;  -- ==> 9 (ví có 1 giá trị null)
  • Đếm giá trị khác nhau trong cột
SELECTCOUNT(DISTINCTcity) FROMemployees; -- 3 (Hà nội, TPHCM, Cần thơ)

1.2. SUM – Tính tổng (doanh thu, số lượng, chi phí…)

SUM dùng để tính tổng các giá trị số trong một cột. Ứng dụng trong:

  • Tính tổng doanh thu, tổng số lượng bán
  • Tổng giá trị đơn hàng

Ví dụ 1:  Tính tổng số lượng sản phẩm tồn kho trong bảng products

SELECT SUM(stock_quantity) AS total_stock
FROM products;

Ví dụ 2:  Tính tổng số lượng sản phẩm đã bán trong bảng order_details

SELECT SUM(quantity) AS total_sold
FROM order_details;

1.3. AVG – Giá trị trung bình

AVG dùng để tính giá trị trung bình của các giá trị số trong một cột. Ứng dụng trong:

  • Tính giá trung bình sản phẩm
  • Tính số lượng trung bình trong đơn hàng
  • Phân tích xu hướng và so sánh

Ví dụ: Tính giá trung bình của sản phẩm

SELECT AVG(price) AS average_price
FROM products;

1.4. MIN – Tìm giá trị nhỏ nhất

MIN dùng để tìm giá trị nhỏ nhất trong một cột (áp dụng cho số, ngày, chuỗi) Ứng dụng trong:

  • Tìm giá thấp nhất
  • Tìm ngày sớm nhất (đơn hàng đầu tiên, ngày gia nhập)
  • So sánh và phân tích

Ví dụ: Tìm sản phẩm có giá thấp nhất

SELECT MIN(price) AS lowest_price
FROM products;

1.5. MAX – Tìm giá trị lớn nhất

MAX dùng để tìm giá trị lớn nhất trong một cột. Ứng dụng trong:

  • Tìm giá cao nhất
  • Tìm ngày gần nhất (đơn hàng mới nhất)
  • Xác định giá trị đỉnh

Ví dụ: Tìm giá cao nhất

SELECT MAX(price) AS highest_price
FROM products;

2. GROUP BY – “Gom nhóm” để nhìn dữ liệu theo lát cắt

GROUP BY dùng để nhóm các bản ghi có cùng giá trị trong một hoặc nhiều cột nhằm thực hiện các phép tính thống kê.

Lưu ý: Tất cả các cột trong SELECT phải nằm trong GROUP BY hoặc nằm trong hàm thống kê (COUNT, SUM, AVG…)

Đếm số đơn hàng theo trạng thái, bảng đơn hàng như sau:

SELECT status, COUNT(*) AS order_count
FROM orders
GROUP BY status;

Chúng ta có được kết quả thống kê theo trạng thái rất hay:


Ví dụ 2: Tính tổng số lượng bán ra theo từng sản phẩm trong bảng  order_details như sau

SELECT product_id, SUM(quantity) AS total_sold
FROM order_details
GROUP BY product_id;

Từng mỗi sản phẩm chúng ta biết nhay tổng số sản phẩm :


Phân tích sản phẩm bán chạy nhất với doanh thu cao nhất

SELECT 
    p.id, p.product_name, p.brand, p.price,
    COUNT(od.order_id) AS times_ordered,
    SUM(od.quantity) AS total_quantity_sold,
    SUM(od.quantity * p.price) AS total_revenue,
    MAX(o.order_date) AS last_sold_date,
    MIN(o.order_date) AS first_sold_date
FROM products p
JOIN order_details od ON p.id = od.product_id
JOIN orders o ON od.order_id = o.id
WHERE o.status = 'Delivered'
GROUP BY p.id, p.product_name, p.brand, p.price
ORDER BY total_revenue DESC
LIMIT 10

Giải thích:

  • FROM và JOIN bảng products, order_details và orders cho tập kết quả là các hàng chi tiết đơn hàng kèm thông tin sản phẩm và đơn hàng.
  • WHERE lọc tập hợp trên chỉ giữ lại các hàng có trạng thái đơn hàng là “Delivered”
  • GROUP BY gom các hàng lại theo tổ hợp p.id, p.product_name, p.brand, p.price. Mỗi tổ hợp tương ứng với một sản phẩm trong bảng products.
  • COUNT(od.order_id) AS times_ordered — đếm số dòng order_details (số hàng order_detail) cho mỗi nhóm.
  • SUM(od.quantity) AS total_quantity_sold — tổng số lượng bán ra (cộng quantity).
  • SUM(od.quantity * p.price) AS total_revenue — tổng doanh thu (nhân quantity với p.price từ bảng products).
  • MAX(o.order_date) AS last_sold_date — ngày bán gần nhất trong nhóm.
  • MIN(o.order_date) AS first_sold_date — ngày bán sớm nhất trong nhóm.
  • ORDER BY total_revenue DESC: sắp xếp các nhóm theo total_revenue giảm dần (từ cao xuống thấp). Ở đây dùng alias total_revenue đã định nghĩa trong SELECT.
  • LIMIT 10: lấy 10 hàng đầu sau khi đã sắp xếp — tức là 10 sản phẩm có tổng doanh thu cao nhất (trong các đơn “Delivered”).

3. HAVING – Lọc theo điều kiện thống kê (lọc nhóm)

HAVING sử dụng để lọc sau khi đã GROUP BY, áp dụng cho kết quả của các hàm thống kê. Ứng dụng

  • Lọc nhóm dữ liệu thỏa mãn điều kiện thống kê
  • Tìm khách hàng VIP (mua nhiều hơn X lần)
  • Tìm sản phẩm bán chạy
  • WHERE lọc dữ liệu trước khi thực hiện GROUP BY, trong khi HAVING được sử dụng để lọc các nhóm dữ liệu sau khi đã thực hiện thống kê.

Ví dụ: Tìm khách hàng có nhiều hơn 1 đơn hàng

SELECT customer_id, COUNT(*) AS order_count
FROM orders
GROUP BY customer_id
HAVING COUNT(*) > 1;

Ví dụ: Tìm sản phẩm có tổng số lượng bán > 3

SELECT product_id, SUM(quantity) AS total_sold
FROM order_details
GROUP BY product_id
HAVING SUM(quantity) > 3;

4. Kết hợp JOIN + GROUP BY + HAVING.

Sử dụng kết hợp JOIN, GROUP BY, HAVING để liên kết nhiều bảng, nhóm dữ liệu và lọc theo điều kiện thống kê để tạo báo cáo phức tạp. Ứng dụng trong:

  • Báo cáo tổng hợp từ nhiều nguồn dữ liệu
  • Phân tích đa chiều
  • Dashboard và KPI

Ví dụ: Tìm khách hàng có tổng giá trị các đơn hàng > 30 triệu

SELECT
c.id,
c.first_name,
c.last_name,
SUM(od.quantity * p.price) AS total_spent
FROM customers c
JOIN orders o ON c.id = o.customer_id
JOIN order_details od ON o.id = od.order_id
JOIN products p ON od.product_id = p.id
WHERE o.status = 'Delivered'
GROUP BY c.id, c.first_name, c.last_name
HAVING SUM(od.quantity * p.price) > 30000000
ORDER BY total_spent DESC;

Ví dụ: Tìm sản phẩm bán chạy (giả sử bán nhiều hơn 3 sản phẩm)

SELECT
p.product_name,
p.brand,
SUM(od.quantity) AS total_sold
FROM products p
JOIN order_details od ON p.id = od.product_id
JOIN orders o ON od.order_id = o.id
WHERE o.status = 'Delivered'
GROUP BY p.id, p.product_name, p.brand
HAVING SUM(od.quantity) > 3
ORDER BY total_sold DESC;

KẾT LUẬN

Truy vấn SQL nâng cao trong PostgreSQL đóng vai trò quan trọng trong quá trình phân tích và khai thác dữ liệu từ cơ sở dữ liệu. Thông qua việc sử dụng các hàm thống kê như COUNT, SUM, AVG, MIN và MAX, kết hợp với GROUP BY để gom nhóm dữ liệu và HAVING để lọc kết quả sau khi thống kê, người dùng có thể tạo ra các báo cáo tổng hợp và phân tích dữ liệu theo nhiều góc nhìn khác nhau.

Ngoài ra, việc kết hợp JOIN với GROUP BY và HAVING còn cho phép khai thác dữ liệu từ nhiều bảng khác nhau, giúp xây dựng các truy vấn phân tích phức tạp phục vụ cho dashboard, báo cáo và các bài toán phân tích dữ liệu trong thực tế.

Khi nắm vững các kỹ thuật trong truy vấn SQL nâng cao trong PostgreSQL, người học có thể xây dựng những truy vấn mạnh mẽ, khai thác dữ liệu hiệu quả và hỗ trợ tốt cho quá trình phân tích dữ liệu cũng như ra quyết định dựa trên dữ liệu trong các hệ thống hiện đại.