Thứ Năm, 27 tháng 7, 2023

Sử dụng Window Function trong PostgreSQL (phần 1)

Trước khi đi vào tìm hiểu về window function, chúng ta hãy ôn tập lại về các hàm aggregate: SUM, COUNT và AVG

Tôi có 2 bảng dữ liệu products và product_groups có quan hệ 1-nhiều như sau:

1 product group gồm nhiều product
1 product group gồm nhiều product

Ta lấy ra nhóm sản phẩm, tên và giá mỗi sản phẩm:

select product_groups.group_name, products.product_name, products.price
from products, product_groups
where products.group_id = product_groups.group_id
Thông tin sản phẩm và giá của từng nhóm
Thông tin sản phẩm và giá của từng nhóm

 Với mỗi nhóm sản phẩm, ta tính được giá trung bình của các sản phẩm trong nhóm bằng cách dùng hàm AVG:

select product_groups.group_name, AVG(products.price) AS average_price
from products, product_groups
where products.group_id = product_groups.group_id
group by product_groups.group_name
Giá trung bình của từng nhóm sản phẩm
Giá trung bình của từng nhóm sản phẩm

Bây giờ, yêu cầu đặt ra là: Hãy tính mức chênh lệch giá của từng sản phẩm so với mức giá trung bình của nhóm. Ví dụ, giá của Microsoft Lumia là 200, Microsoft Lumia thuộc nhóm sản phẩm Smartphone có mức giá trung bình là 500 --> chênh lệch giá là 200 - 500 = -300

Ta có thể dùng Sub-Query trong mệnh đề WHERE như sau:

select product_groups.group_id, products.product_name, products.price, 
group_avg_price.average_price,
(products.price - group_avg_price.average_price) AS price_diff
from products, product_groups, 
(
	select product_groups.group_id AS group_id, 
    AVG(products.price) AS average_price
	from products, product_groups
	where products.group_id = product_groups.group_id
	group by product_groups.group_id
) group_avg_price
where products.group_id = product_groups.group_id
and product_groups.group_id = group_avg_price.group_id

 

Kết quả thu được bằng cách dùng Sub-Query
Kết quả thu được bằng cách dùng Sub-Query

Cách làm trên cho kết quả đúng, tuy nhiên câu lệnh SQL trông hơi dài và rối. Ta có thể dùng một cách khác ngắn gọn hơn:

select product_groups.group_id, products.product_name, products.price, 
AVG(price) OVER (PARTITION BY product_groups.group_id) AS average_price, 
( products.price - AVG(price) OVER (PARTITION BY product_groups.group_id) ) AS price_diff
from products, product_groups
where products.group_id = product_groups.group_id
Code ngắn hơn, kết quả vẫn chính xác
Code ngắn hơn, kết quả vẫn chính xác

Ta vẫn dùng hàm AVG() để tính trung bình, tuy nhiên khác biệt ở đây chính là mệnh đề OVER (PARTITION BY product_groups.group_id) ở đằng sau.

Vậy thì, mệnh đề này có tác dụng gì ?

PARTITION BY product_groups.group_id sẽ chia dữ liệu thành các khối riêng biệt dựa trên giá trị của cột product_groups.group_id, mỗi một khối dữ liệu được gọi là 1 window

3 khối dữ liệu được chia theo group_id
3 khối dữ liệu được chia theo group_id

Sau khi đã chia dữ liệu thành 3 khối, hàm AVG() sẽ được chạy cho từng khối, tức là nó sẽ tính toán giá trị trung bình cho từng khối một. Đến đây, các bạn có thể thấy nó khá giống với việc chúng ta dùng hàm AVG() kết hợp với GROUP BY như ở phần đầu bài viết. Điểm khác biệt quan trọng nhất là: GROUP BY sẽ "gom" các bản ghi lại, trong khi với PARTITION BY các bản ghi sẽ không bị "gom" lại và mỗi bản ghi trong một khối (window) sẽ nhận được giá trị trung bình tương ứng của khối đó. 

Thêm một ví dụ khác, lần này ta dùng SUM() để tính tổng giá của từng nhóm sản phẩm:

select product_groups.group_id, products.product_name, products.price, 
AVG(price) OVER (PARTITION BY product_groups.group_id) AS average_price, 
SUM(price) OVER (PARTITION BY product_groups.group_id) AS total_price,
( products.price - AVG(price) OVER (PARTITION BY product_groups.group_id) ) AS price_diff
from products, product_groups
where products.group_id = product_groups.group_id
SUM() kết hợp với OVER (PARTITION BY)
SUM() kết hợp với OVER (PARTITION BY)

Trong các bài viết sau, chúng ta sẽ tiếp tục tìm hiểu cách sử dụng window function để giải quyết các yêu cầu đọc và tính toán dữ liệu 

=============================
* KHOÁ HỌC ORACLE DATABASE A-Z ENTERPRISE trực tiếp từ tôi giúp bạn bước đầu trở thành những chuyên gia DBA, đủ kinh nghiệm đi thi chứng chỉ OA/OCP, đặc biệt là rất nhiều kinh nghiệm, bí kíp thực chiến trên các hệ thống Core tại VN chỉ sau 1 khoá học.
* CÁCH ĐĂNG KÝ: Gõ (.) hoặc để lại số điện thoại hoặc inbox https://m.me/tranvanbinh.vn hoặc Hotline/Zalo 090.29.12.888
* Chi tiết tham khảo:
https://bit.ly/oaz_w
=============================
KẾT NỐI VỚI CHUYÊN GIA TRẦN VĂN BÌNH:
📧 Mail: binhoracle@gmail.com
☎️ Mobile/Zalo: 0902912888
👨 Facebook: https://www.facebook.com/BinhOracleMaster
👨 Inbox Messenger: https://m.me/101036604657441 (profile)
👨 Fanpage: https://www.facebook.com/tranvanbinh.vn
👨 Inbox Fanpage: https://m.me/tranvanbinh.vn
👨👩 Group FB: https://www.facebook.com/groups/DBAVietNam
👨 Website: https://www.tranvanbinh.vn
👨 Blogger: https://tranvanbinhmaster.blogspot.com
🎬 Youtube: https://www.youtube.com/@binhguru
👨 Tiktok: https://www.tiktok.com/@binhguru
👨 Linkin: https://www.linkedin.com/in/binhoracle
👨 Twitter: https://twitter.com/binhguru
👨 Podcast: https://www.podbean.com/pu/pbblog-eskre-5f82d6
👨 Địa chỉ: Tòa nhà Sun Square - 21 Lê Đức Thọ - Phường Mỹ Đình 1 - Quận Nam Từ Liêm - TP.Hà Nội

=============================
Sử dụng Window Function trong PostgreSQL (phần 1), oracle tutorial, học oracle database, Tự học Oracle, Tài liệu Oracle 12c tiếng Việt, Hướng dẫn sử dụng Oracle Database, Oracle SQL cơ bản, Oracle SQL là gì, Khóa học Oracle Hà Nội, Học chứng chỉ Oracle ở đầu, Khóa học Oracle online,sql tutorial, khóa học pl/sql tutorial, học dba, học dba ở việt nam, khóa học dba, khóa học dba sql, tài liệu học dba oracle, Khóa học Oracle online, học oracle sql, học oracle ở đâu tphcm, học oracle bắt đầu từ đâu, học oracle ở hà nội, oracle database tutorial, oracle database 12c, oracle database là gì, oracle database 11g, oracle download, oracle database 19c, oracle dba tutorial, oracle tunning, sql tunning , oracle 12c, oracle multitenant, Container Databases (CDB), Pluggable Databases (PDB), oracle cloud, oracle security, oracle fga, audit_trail,oracle RAC, ASM, oracle dataguard, oracle goldengate, mview, oracle exadata, oracle oca, oracle ocp, oracle ocm , oracle weblogic, postgresql tutorial, mysql tutorial, mariadb tutorial, ms sql server tutorial, nosql, mongodb tutorial, oci, cloud, middleware tutorial, hoc solaris tutorial, hoc linux tutorial, hoc aix tutorial, unix tutorial, securecrt, xshell, mobaxterm, putty

ĐỌC NHIỀU

Trần Văn Bình - Oracle Database Master