Tiếp nối bài viết SQL trong Data Analysis: Nhập môn SQL cơ bản, ở bài này chúng ta sẽ đi sâu vào từ khóa JOINs , cũng như các câu truy vấn liên quan tới nó.
Giới thiệu
Các câu lệnh có từ khóa JOINs được dùng trong SQL để kết hợp các dòng dữ liệu từ hai bảng trở lên. Có 05 loại JOINs cơ bản như sau: INNER JOIN, LEFT JOIN, RIGHT JOIN, FULL JOIN, CROSS JOIN.
Tuy SQL là một ngôn ngữ truy vấn dữ liệu cấu trúc chung (Structured Query Language), tuy nhiên không phải cơ sở dữ liệu nào cũng hỗ trợ đủ 05 loại JOINs cơ bản trên. Như MySQL không hỗ trợ FULL JOIN hoặc PostgreSQL ngoài 05 loại trên, thì còn hỗ trợ các loại JOINs khác như: SELF JOIN, NATURAL JOIN.
Ở trong bài viết này, chúng ta sẽ chỉ nói tới PostgreSQL thôi. Lưu ý: mẫu data chúng ta sử dụng sẽ từ Kaggle, nếu bạn chưa cài đặt sẵn vào Postgres thì hãy xem lại bài này nhé.
Kiểm tra dữ liệu
Chúng ta sẽ sử dụng 02 bảng dữ liệu sau:
“brazilian-ecommerce”.olist_products_dataset
“brazilian-ecommerce”.product_category_name_translation
INNER JOIN
INNER JOIN sẽ chỉ lấy dữ liệu từ có xuất hiện ở cả 2 bảng.
Để cho đơn giản, chúng ta sẽ chỉ quan tâm tới 2 product_id sau: dc6518b93adefc206b0d220c057f8b56 và 3014e35fd70fce29095ced5cdc89f4ce và 12f066474dfa3c415c169051c5e1967e.
select opd.product_id, pcnt.product_category_name, pcnt.product_category_name_english
from "brazilian-ecommerce".olist_products_dataset opd
inner join "brazilian-ecommerce".product_category_name_translation pcnt
on opd.product_category_name = pcnt.product_category_name
where opd.product_id in ('dc6518b93adefc206b0d220c057f8b56', '3014e35fd70fce29095ced5cdc89f4ce', '12f066474dfa3c415c169051c5e1967e');
Dữ liệu trả về sẽ chỉ có 02 dòng, được liên kết bởi product_category_name. Lúc này dữ liệu chỉ lấy ra cột product_id từ bảng product và category name (tiếng Tây Ban Nha), và category name bản tiếng Anh.
LEFT JOIN
LEFT JOIN sẽ lấy mọi dữ liệu xuất hiện ở bảng bên trái, nếu các dữ liệu bên bảng bên phải có liên kết thông qua điều kiện JOIN cũng sẽ xuất hiện.
select opd.product_id, pcnt.product_category_name, pcnt.product_category_name_english
from "brazilian-ecommerce".olist_products_dataset opd
left join "brazilian-ecommerce".product_category_name_translation pcnt
on opd.product_category_name = pcnt.product_category_name
where opd.product_id in ('dc6518b93adefc206b0d220c057f8b56', '3014e35fd70fce29095ced5cdc89f4ce',
'12f066474dfa3c415c169051c5e1967e');
Dữ liệu lúc này sẽ trả về 03 dòng.
RIGHT JOIN
RIGHT JOIN giống LEFT JOIN sẽ lấy mọi dữ liệu xuất hiện, tuy nhiên sẽ chỉ ở bảng bên phải, nếu các dữ liệu bên bảng bên trái có liên kết thông qua điều kiện JOIN cũng sẽ xuất hiện.
Lúc này chúng ta sẽ đổi điều kiện WHERE một chút để thấy rõ hơn dữ liệu từ bảng product_category_name_translation được trả về.
select opd.product_id, pcnt.product_category_name, pcnt.product_category_name_english
from "brazilian-ecommerce".olist_products_dataset opd
right join "brazilian-ecommerce".product_category_name_translation pcnt
on opd.product_category_name = pcnt.product_category_name
where pcnt.product_category_name_english = 'telephony';
Lúc này, dữ liệu được trả về toàn bộ đều thuộc về category-name ‘telephony’.
Để thấy rõ hơn, bạn có thể thêm vào điều kiện WHERE như sau:
select opd.product_id, pcnt.product_category_name, pcnt.product_category_name_english
from "brazilian-ecommerce".olist_products_dataset opd
right join "brazilian-ecommerce".product_category_name_translation pcnt
on opd.product_category_name = pcnt.product_category_name
where pcnt.product_category_name_english = 'telephony'
and opd.product_id in ('dc6518b93adefc206b0d220c057f8b56', '3014e35fd70fce29095ced5cdc89f4ce',
'12f066474dfa3c415c169051c5e1967e');
Lúc này, dữ liệu trả về chỉ còn có 02 dòng, và bạn thấy rằng chỉ có product có category là ‘telephony’ được trả về, product có category null thì bị loại ra.
FULL JOIN
Từ khoá FULL JOIN (hay cũng có thể viết là FULL OUTER JOIN, kết quả đều như nhau) sẽ kết hợp dữ liệu của 02 bảng lại dù cho điều kiện kiện liên kết có thoả hay không.
Note: Vì bộ dữ liệu này không có trường hợp để thử nghiệm từ khoá này. Nên bạn cần phải insert thêm 01 dòng dữ liệu vào bảng “brazilian-ecommerce”.product_category_name_translation nhé.
insert into "brazilian-ecommerce".product_category_name_translation values ('test','test');
Dữ liệu test đã sẵn sàng, vậy chúng ta thử chạy câu lệnh dưới đây để truy xuất dữ liệu:
select opd.product_id, pcnt.product_category_name, pcnt.product_category_name_english
from "brazilian-ecommerce".olist_products_dataset opd
full join "brazilian-ecommerce".product_category_name_translation pcnt
on opd.product_category_name = pcnt.product_category_name
where opd.product_id in ('dc6518b93adefc206b0d220c057f8b56', '3014e35fd70fce29095ced5cdc89f4ce',
'12f066474dfa3c415c169051c5e1967e') or pcnt.product_category_name_english in (null, 'telephonia', 'test');
Kết quả trả về đều sẽ 02 dòng dữ liệu có liên kết và 02 dòng dữ liệu không có liên kết như hình dưới.
CROSS JON
CROSS JOIN là một từ khoá JOIN khá đặc biệt. Khi nhiệm vụ của nó là liên kết mọi đối tượng trong bảng T1 liên kết với bảng T2 (như hình trên). Như vậy vì chỉ cần tạo mọi liên kết có thể nên từ khoá này sẽ không cần điều kiện join (từ khoá ON).
select opd.product_id, pcnt.product_category_name, pcnt.product_category_name_english
from "brazilian-ecommerce".olist_products_dataset opd
cross join "brazilian-ecommerce".product_category_name_translation pcnt
where opd.product_id in ('dc6518b93adefc206b0d220c057f8b56', '3014e35fd70fce29095ced5cdc89f4ce',
'12f066474dfa3c415c169051c5e1967e') order by opd.product_id;
Kết quả sẽ như sau:
Tổng kết
Qua bài này, bạn đã nắm được 05 từ khoá JOIN trong truy vấn dữ liệu. Các từ khoá này là kiến thức nền tảng để phục vụ công việc của bạn sau này. Hy vọng bạn sẽ nắm chắc được, để chúng ta sẽ đi tiếp với các bài trong chuỗi bài SQL trong data analysis nhé.
Xin cám ơn.