SQL trong Data Analysis: Sử dụng CTE (Common Table Expression)

Nội dung

Xin chào các bạn đã quay lại chuỗi bài SQL trong Data Analysis. Ở bài này, chúng ta sẽ tập làm quen sử dụng Common Table Expression (CTE) trong SQL.

Giới thiệu

Common Table Expression là một công cụ trong SQL cho phép bạn tạo một tên bảng tạm thời và sử dụng nó trong câu truy vấn hiện tại. CTE có thể được sử dụng để xây dựng các truy vấn phức tạp, thường đi kèm với các câu lệnh SELECT, INSERT, UPDATE hoặc DELETE.

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

SQL
WITH cte_name (column_list) AS (
    CTE_query_definition 
)
statement;

Thực hành

Làm quen

Chúng ta sẽ thử sử dụng CTE vào câu truy vấn đơn giản như sau: Lấy các reviews gắn liền với các đơn hàng được trong năm 2017. Lưu ý: thực tế đơn được đặt năm 2017, thì khách hàng vẫn có thể để lại review ở năm 2017, hoặc thậm chí 2019, tuỳ theo hệ thống “linh động” như thế nào.

SQL
with only_2017 as (
	select * from "brazilian-ecommerce".olist_orders_dataset as d
	where extract(year from d.order_purchase_timestamp::date) = '2017'
)
select * from "brazilian-ecommerce".olist_order_reviews_dataset oord  
	inner join only_2017 as ol on oord.order_id = ol.order_id;

Kết quả

SQL trong Data Analysis: Sử dụng CTE (Common Table Expression): Làm quen

Nếu bạn để ý, sẽ thấy yêu cầu truy vấn sẽ tương tự như đoạn SQL dưới đây:

SQL
select * from "brazilian-ecommerce".olist_orders_dataset as d
	inner join "brazilian-ecommerce".olist_order_reviews_dataset as o 
	on o.order_id = d.order_id
where extract(year from d.order_purchase_timestamp::date) = '2017'

Thực ra, mục tiêu của CTE được dùng để đơn giản hoá việc viết SQL đối với câu lệnh truy vấn JOINs trên nhiều bảng hoặc các SubQueries phức tạp.

Vấn đề nâng cao

Ví dụ như đoạn dưới đây, với các viết truy vấn CTE thì chúng ta sẽ thấy cách viết sẽ đơn giản và dễ hiểu hơn hẳn. Đề bài: phòng trải nghiệm khách hàng (CX) muốn tìm hiểu các yếu tố nào ảnh hưởng tới lượt review thấp, trong đó có giả thuyết thời gian giao hàng quá lâu sẽ ảnh hưởng trực tiếp tới sự hài lòng của khách hàng.

SQL
with only_deliveried_2017 as (
	select *, EXTRACT(epoch from (d."order_delivered_customer_date"::timestamp - d."order_purchase_timestamp"::timestamp))/3600 as hours_2_d
	from "brazilian-ecommerce".olist_orders_dataset as d
	where extract(year from d.order_purchase_timestamp::date) = '2017'
	and d.order_delivered_customer_date <> ''
), review_lt_3 as (
	select * from "brazilian-ecommerce".olist_order_reviews_dataset oord  
		inner join only_deliveried_2017 as ol on oord.order_id = ol.order_id
		where oord.review_score < 3
), review_gt_3 as (
	select * from "brazilian-ecommerce".olist_order_reviews_dataset oord  
	inner join only_deliveried_2017 as ol on oord.order_id = ol.order_id
	where oord.review_score > 3
)
select avg(review_lt_3.hours_2_d) as lt_3_avg, avg(review_gt_3.hours_2_d) as gt_3_avg
from review_lt_3, review_gt_3;

Kết quả

SQL trong Data Analysis: Sử dụng CTE (Common Table Expression): Kết quả làm quen

Đoạn truy vấn trên tính tập dữ liệu đơn hàng xuất hiện trong 2017, và tính trung bình tỉ lệ reviews với nhóm đơn hàng 2017 thành 02 chỉ số cho nhóm dưới 03 và nhóm trên 03. Như vậy, nếu không dùng CTE, chúng ta phải viết 02 câu truy vấn khác nhau (thay vào chỗ from review_lt_3, review_gt_3, và tệp đơn hàng 2017 sẽ phải xuất hiện 02 lần).

Fact 1: để trả lời được một câu hỏi đơn giản như thế, chúng ta phải chuẩn bị dữ liệu rất nhiều. Và thậm chí đoạn truy vấn trên cũng tốn thời gian để tính toán (Ở trên máy bàn CPU i7 đời thứ 12 và 32GB RAM vẫn cần tới ~25 giây để tính toán xong, nếu máy tính các bạn không đủ mạnh, có thể không cần chạy truy vấn này, tuy nhiên mình khuyến khích nên chạy và thử nghiệm).

Fact 2: để chứng minh sự liên hệ giữa 02 chỉ số với nhau, chúng ta có thể tính tỉ lệ thuận/nghịch không thay đổi của 02 chỉ số này. Trong trường hợp này chúng ta thấy để trung bình reviews trên 3 thì thời gian giao hàng trung bình phải ít hơn 281 giờ và ngược lại. Để đảm bảo, chúng ta có thể sẽ phải tính lại trên nhiều điều kiện dữ liệu khác nhau, ví dụ 2018 hoặc chỉ một nhóm hàng nhất định.

Thực hành + Ôn tập

Lần này chúng ta sẽ thử kết hợp với Window Functions đã học trước đó. Đặt giả sử, chúng ta cho là cận nặng của sản phẩm sẽ ảnh hưởng tới việc mua hàng. Cho nên chúng ta sẽ cần chạy dữ liệu để chứng minh nếu cân nặng của sản phẩm tỷ lệ thuận/tỷ lệ nghịch với số lượng mua.

SQL
with product_weight_ranking as (
	select product_id, product_weight_g, CUME_DIST() OVER (
			ORDER by product_weight_g 
		) as weight_ranking
	from "brazilian-ecommerce".olist_products_dataset
),
sale_data as (
	select product_id, count(product_id) as sold_count 
	from "brazilian-ecommerce".olist_order_items_dataset group by 1
),
ranking_product_sale as (
	select product_id, sold_count, cume_dist () over (
		order by sold_count
	) as sale_ranking from sale_data
)
select s.product_id, sold_count, sale_ranking, product_weight_g, weight_ranking from ranking_product_sale s
	inner join product_weight_ranking w on s.product_id = w.product_id;

Kết quả

SQL trong Data Analysis: Sử dụng CTE (Common Table Expression): Dùng với Window Function

Kết luận: Chà có vẻ không phải cái gì chúng ta nghĩ cũng đúng nhỉ.

Tổng kết

Qua bài này chúng ta đã học thêm về Common Table Expression (CTE). Một số lợi ích khi sử dụng CTE bao gồm: giúp chúng ta dễ sắp xếp và đọc code hơn, giúp chúng ta tái sử dụng những đoạn truy vấn trùng, và còn là một trong những cách truy vấn đệ quy (ví dụ, cùng 01 bảng dữ liệu nhân viên, cần sắp xếp kiếm theo cấp bậc: giám đốc, quản lý, nhân viên).

Ngoài ra, chúng ta cũng đã đi “dạo” một vòng công việc của một Data Analyst thực thụ. Khi chúng ta đã thử rút trích “insight” từ dữ liệu thô. Như tỉ lệ mức độ hài lòng liên quan tới thời gian giao hàng, và cân nặng của sản phẩm không liên quan gì số lượng bán.

Xin cám ơn.

Bài viết liên quan

SQL trong Data Analysis: Procedure và Function – 2 công cụ không thể thiếu

Xin chào các bạn đã quay trở lại chuỗi bài SQL trong Data Analysis...

Tự học Data Analyst: Tổng hợp chuỗi bài SQL 101 trong Data Analysis

Trong bài viết này, chúng ta sẽ tổng hợp các bài viết thành một...

SQL trong Data Analysis: Hiểu rõ và ứng dụng đệ quy (Recursive trong PostgreSQL)

Trong thế giới của cơ sở dữ liệu quan hệ, các truy vấn đệ...

[Phân Tích Dữ Liệu Với Python] Tập 1: Làm Quen Với Pandas

Trong thời đại tiến bộ của khoa học dữ liệu, khả năng phân tích...
spot_img