Hế lô anh em ✌️✌️✌️
Việc kết hợp dữ liệu giữa các bảng để đạt được các mục đích truy vấn sao cho phù hợp với nghiệp vụ gần như là yêu cầu bắt buộc khi chúng ta làm việc với cơ sở dữ liệu của các hệ thống lớn.
Trong số các câu lệnh được sử dụng cho mục đích đó thì các lệnh JOIN
vẫn là phổ biến nhất. Và trong bài viết hôm nay mình sẽ cùng anh em tìm hiểu về INNER JOIN
- câu lệnh JOIN
được sử dụng gần phổ biến nhất.
1/ Định nghĩa, Tính chất, Cú pháp
1.1 - Định nghĩa.
Câu lệnh INNER JOIN
cho phép chúng ta kết hợp dữ liệu từ một hàng của bảng này với dữ liệu từng hàng của bảng khác thành một hàng duy nhất.
1.2 - Tính chất.
Để dễ hiểu các bạn hình dung nó như các vòng for
lồng nhau vậy. Nếu table_1 có a
bản ghi, table_2 có b
bản ghi, table_3 có c
bản ghi ... table_n có k
bản ghi thì số hàng được tạo ra khi INNER JOIN
tất cả các bảng lại sẽ là: a * b * c * ... * k
(hàng)
Tương tự nếu table_1 có x
cột, table_2 có y
cột, table_3 có q
cột ... table_n có k
cột thì sau khi INNER JOIN
tất cả các bảng đó lại chúng ta sẽ có: x + y + q + k
(cột)
Nhưng thông thường câu lệnh INNER JOIN
sẽ kèm theo điều kiện là hai bảng join với nhau thì một trong hai bảng phải có một trường để tham chiếu đến trường tương ứng trong bảng kia.
1.3 - Cú pháp.
Cú pháp tổng quát của câu lệnh này như sau:
SELECT
select_list
FROM t1
INNER JOIN t2 ON join_condition1
INNER JOIN t3 ON join_condition2
...;
Ví dụ chúng ta có hai bảng dữ liệu: table1
(studentId, studentName, studentCode, classId) và table2
(classId, className, classCode).
Chúng ta muốn lấy ra thông tin: studentName, studentCode, className và classCode của mỗi học sinh thì phải làm như thế nào?
Đơn giản thôi chúng ta sẽ thực hiện INNER JOIN
hai bảng table1
và table2
như sau:
SELECT
t1.studentName ,
t1.studentCode ,
t2.className ,
t2.classCode
FROM table1 t1 INNER JOIN table2 t2 ON t1.classId = t2.classId;
Ở đây anh em thấy cấu trúc INNER JOIN ... ON
. Ngoài ra anh em cũng có thể sử dụng INNER JOIN ... USING
như sau:
SELECT
t1.studentName ,
t1.studentCode ,
t2.className ,
t2.classCode
FROM table1 t1 INNER JOIN table2 t2 USING(classId);
Note:
Điểm khác nhau giữa ON
và USING
là gì? Đó là khi sử dụng USING
tên của hai trường để JOIN
ở mỗi bảng phải giống nhau (như trong ví dụ trên thì cùng là classId). Còn khi sử dụng ON
thì không nhất thiết hai trường này phải có tên giống nhau.
2/ Ví dụ.
Trong phần ví dụ này anh em có thể database mẫu mình sử dụng tại đây.
Ví dụ 1: Kết hợp INNER JOIN và GROUP BY
Trong ví dụ này mình sẽ sử dụng hai bảng đó là orders
và orderdetails
. Cấu trúc của hai bảng này anh em có thể thấy bên dưới như sau:
Quan hệ ở đây là một orders
có thể có nhiều orderdetails
. Bây giờ mình muốn biết xem với mỗi yêu cầu của khách hàng (order) thì họ đã chi trả bao nhiêu.
Cũng đơn giản thôi, chúng ta lấy quantityOrdered * priceEach
sẽ ra được chi phí của một orderdetail
. Sau đó chỉ cần tính tổng tất cả các orderdetail
của order
là sẽ ra được con số cuối cùng.
Câu query lúc này sẽ như sau:
SELECT
t1.orderNumber,
t1.customerNumber ,
SUM(quantityOrdered * priceEach) total
FROM
orders t1
INNER JOIN orderdetails t2
ON t1.orderNumber = t2.orderNumber
GROUP BY orderNumber;
Mình có bổ sung thêm hai trường là orderNumber
và customerNumber
trong phần output để chúng ta dễ dàng so sánh số liệu.
Kết quả như sau:
orderNumber|customerNumber|total |
-----------+--------------+--------+
10100| 363|10223.83|
10101| 128|10549.01|
10102| 181| 5494.78|
10103| 121|50218.95|
10104| 141|40206.20|
10105| 145|53959.21|
10106| 278|52151.81|
10107| 131|22292.62|
... | ...|... |
Nếu trong trường hợp này các bạn chỉ INNER JOIN
mà không GROUP BY
thì câu query sẽ trả ra total là tổng của toàn bộ order
vì chúng ta đang sử dụng hàm SUM()
.
Đây cũng là một case study chúng ta gặp khá nhiều trong thực tế, các bạn có thể nhớ để vận dụng.
Ví dụ 2: Kết hợp 3 bảng sử dụng INNER JOIN
Thực tế thì việc chúng ta phải join nhiều hơn 2 bảng là rất nhiều vì nguyên nhân nghiệp vụ phức tạp hay đôi khi là do người thiết kế cơ sở dữ liệu chưa tối ưu...
Trong ví dụ tiếp theo này mình sẽ sử dụng thông tin ở 3 bảng: products
, orderdetails
và orders
. Cấu trúc của ba bảng này anh em có thể thấy bên dưới như sau:
Để có thể join 3 bảng lại với nhau thì chúng ta join lần lượt hai trong 3 bảng đó với nhau. Như vậy nếu có n bảng thì để join hết những bảng đó lại chúng ta cần n-1 câu lệnh JOIN.
Và như mình đã đề cập bên trên thì thông thường việc join các bảng sẽ kèm theo điều kiện nên ở mỗi hai bảng được join với nhau phải có một trường gọi là khóa ngoại để liên kết.
Ví dụ này chúng ta có orders
liên kết với orderdetails
thông qua orderNumber
và orderdetails
liên kết với products
thông qua productCode
. Như vậy khi join 3 bảng này lại chúng ta sẽ làm như sau:
SELECT
orderNumber,
orderDate,
orderLineNumber,
productName,
quantityOrdered,
priceEach
FROM orders
INNER JOIN orderdetails USING (orderNumber)
INNER JOIN products USING (productCode)
Ở đây, mình lấy ra thông tin các trường orderNumber
(orders || orderdetails), orderDate
(orders), orderLineNumber
(orderdetails), productName
(products), quantityOrdered
(orderdetails), priceEach
(orderdetails)
Anh em thấy rằng việc sử dụng cú pháp USING
giúp cho câu truy vấn trở nên ngắn gọn hơn. Nhưng câu hỏi là liệu nhìn vào câu query bên trên anh em có nhớ được trường nào ở bảng nào không?
Mình tin chắc là nếu chỉ với nhiêu đây thì anh em nhớ được nhưng thực tế có những câu query lấy ra cả mấy chục trường thì làm sao để chỉ nhìn vào câu query chúng ta biết trường đó lấy ở bảng nào.
Vì vậy mình hay viết câu query bên trên như sau:
SELECT
o.orderNumber,
o.orderDate,
od.orderLineNumber,
p.productName,
od.quantityOrdered,
od.priceEach
FROM orders o
INNER JOIN orderdetails od ON o.orderNumber = od.orderNumber
INNER JOIN products p ON od.productCode = p.productCode
Nhìn vào câu query này chúng ta sẽ biết ngay được các trường được lấy từ bảng nào và tránh được một lỗi rất hay gặp đó là:
SQL Error [1052] [23000]: Column [column name] in field list is ambiguous
Output của câu query bên trên như sau:
orderNumber|orderDate |orderLineNumber|productName |quantityOrdered|priceEach|
-----------+----------+---------------+-------------------------------------------+---------------+---------+
10100|2003-01-06| 3|1917 Grand Touring Sedan | 30| 136.00|
10100|2003-01-06| 2|1911 Ford Town Car | 50| 55.09|
10100|2003-01-06| 4|1932 Alfa Romeo 8C2300 Spider Sport | 22| 75.46|
10100|2003-01-06| 1|1936 Mercedes Benz 500k Roadster | 49| 35.29|
10101|2003-01-09| 4|1932 Model A Ford J-Coupe | 25| 108.06|
10101|2003-01-09| 1|1928 Mercedes-Benz SSK | 26| 167.06|
... |... | ...|... | ...| ...|
Tương tự cho việc kết hợp 4 hay 5 bảng sử dụng câu lệnh INNER JOIN cũng sẽ như vậy.
3/ Lời kết.
Tầm quan trọng của các câu lệnh JOIN trong các hệ quản trị cơ sở dữ liệu có quan hệ thì không phải bàn cãi rồi. Đặc biệt là câu lệnh INNER JOIN mà mình vừa giới thiệu với anh em bên trên.
Hi vọng qua bài viết này sẽ giúp anh em hiểu được về cách sử dụng cũng như một vài lưu ý khi sử dụng câu lệnh này.
Hẹn gặp lại anh em trong các bài viết tiếp theo!
Tham khảo:
https://www.mysqltutorial.org/mysql-inner-join.aspx
Thank all ❤️❤️❤️
Không có nhận xét nào: