LEFT JOIN (hay còn gọi là LEFT OUTER JOIN) là loại liên kết cho phép kết hợp dữ liệu từ hai bảng, trong đó bảng bên trái (bảng đầu tiên được khai báo) sẽ trả về tất cả các hàng, dù có hoặc không có giá trị tương ứng trong bảng bên phải. Nếu không có bản ghi nào tương ứng trong bảng bên phải, các trường của bảng bên phải sẽ được trả về với giá trị NULL.

Cú pháp của LEFT JOIN:

Customers

Kết quả:

CustomerName Product
John Smith Laptop
Ana Williams Smartphone
Maria Anders NULL

Giải thích:

  • John SmithAna Williams có đơn hàng, nên thông tin đơn hàng của họ được hiển thị.
  • Maria Anders không có đơn hàng, nhưng vì sử dụng LEFT JOIN, tên của cô ấy vẫn xuất hiện trong kết quả, và giá trị của cột Product sẽ là NULL.

So sánh LEFT JOIN và INNER JOIN:

  • INNER JOIN chỉ trả về các hàng có giá trị khớp trong cả hai bảng.
  • LEFT JOIN trả về tất cả các hàng từ bảng bên trái, và các giá trị từ bảng bên phải nếu có bản ghi khớp. Nếu không có, các giá trị từ bảng bên phải sẽ là NULL.

Ví dụ nâng cao với LEFT JOIN:

Giả sử bạn có thêm một bảng Products và bạn muốn kết hợp thông tin khách hàng, sản phẩm mà họ đã mua và giá của sản phẩm. Nếu một khách hàng chưa có đơn hàng, thông tin của họ vẫn sẽ xuất hiện trong kết quả.

Bảng Products:

ProductID ProductName Price
1001 Laptop 800
1002 Smartphone 500

Bây giờ bạn muốn liệt kê tất cả các khách hàng và thông tin về sản phẩm mà họ đã mua (nếu có):

Customers

Kết quả:

CustomerName ProductName Price OrderDate
John Smith Laptop 800 2024-01-01
John Smith Tablet 300 2024-01-05
Ana Williams Smartphone 500 2024-01-03
Maria Anders NULL NULL NULL
Bob Brown NULL NULL NULL

Giải thích:

  • John Smith đã mua 2 sản phẩm (LaptopTablet), và các sản phẩm kèm theo giá và ngày đặt hàng được hiển thị.
  • Ana Williams đã mua Smartphone.
  • Maria AndersBob Brown chưa có đơn hàng, nhưng vẫn xuất hiện trong kết quả với giá trị NULL cho các cột liên quan đến sản phẩm và đơn hàng.

Sử dụng LEFT JOIN với hàm tổng hợp (Aggregate Functions)

Giả sử bạn muốn biết tổng số tiền mà mỗi khách hàng đã chi tiêu, kể cả những khách hàng chưa mua gì (tổng tiền sẽ là NULL đối với những khách hàng đó). Bạn có thể sử dụng hàm SUM()GROUP BY để tính toán tổng giá trị đơn hàng của mỗi khách hàng:

SELECT Customers.CustomerName, SUM(Products.Price) AS TotalSpent
FROM Customers
LEFT JOIN Orders ON Customers.CustomerID = Orders.CustomerID
LEFT JOIN Products ON Orders.ProductID = Products.ProductID
GROUP BY Customers.CustomerName;

Kết quả:

CustomerName TotalSpent
John Smith 1100
Ana Williams 500
Maria Anders NULL
Bob Brown NULL

Giải thích:

  • John Smith đã chi tổng cộng 1100 (800 cho Laptop + 300 cho Tablet).
  • Ana Williams đã chi 500 cho Smartphone.
  • Maria AndersBob Brown chưa mua sản phẩm nào, vì vậy tổng tiền của họ là NULL.

Ví dụ nâng cao với điều kiện lọc:

Nếu bạn muốn chỉ lấy danh sách khách hàng chưa có đơn hàng, bạn có thể sử dụng điều kiện lọc với WHERE để kiểm tra xem cột OrderID từ bảng Orders có giá trị NULL hay không:

SELECT Customers.CustomerName
FROM Customers
LEFT JOIN Orders ON Customers.CustomerID = Orders.CustomerID
WHERE Orders.OrderID IS NULL;

Kết quả:

CustomerName
Maria Anders
Bob Brown

Giải thích:

  • Truy vấn này trả về danh sách các khách hàng chưa có đơn hàng nào (giá trị NULL trong cột OrderID).

Ví dụ với Alias (Bí danh) và LEFT JOIN

Để làm cho truy vấn gọn gàng và dễ hiểu hơn, bạn có thể sử dụng bí danh cho các bảng. Đây là cách sử dụng bí danh cho cùng một truy vấn nâng cao với LEFT JOIN:

SELECT C.CustomerName, P.ProductName, P.Price, O.OrderDate
FROM Customers C
LEFT JOIN Orders O ON C.CustomerID = O.CustomerID
LEFT JOIN Products P ON O.ProductID = P.ProductID;

Kết quả tương tự với các ví dụ trước, nhưng việc sử dụng bí danh (C, O, P) giúp câu truy vấn ngắn gọn và dễ đọc hơn.


Sử dụng LEFT JOIN với điều kiện HAVING

Nếu bạn muốn lấy danh sách các khách hàng đã chi tiêu trên một mức nào đó, ví dụ như hơn 500, bạn có thể sử dụng HAVING với điều kiện:

SELECT Customers.CustomerName, SUM(Products.Price) AS TotalSpent
FROM Customers
LEFT JOIN Orders ON Customers.CustomerID = Orders.CustomerID
LEFT JOIN Products ON Orders.ProductID = Products.ProductID
GROUP BY Customers.CustomerName
HAVING TotalSpent > 500;

Kết quả:

CustomerName TotalSpent
John Smith 1100

Giải thích:

  • Truy vấn này chỉ trả về những khách hàng có tổng số tiền chi tiêu lớn hơn 500. Trong trường hợp này, chỉ có John Smith thỏa mãn điều kiện.

Khi nào nên sử dụng LEFT JOIN thay vì INNER JOIN?

  • LEFT JOIN phù hợp khi bạn muốn giữ tất cả dữ liệu từ bảng bên trái và chỉ bổ sung dữ liệu từ bảng bên phải nếu có sự khớp. Nó đảm bảo rằng không có dữ liệu từ bảng bên trái bị mất, ngay cả khi không có bản ghi tương ứng trong bảng bên phải.
  • INNER JOIN chỉ nên dùng khi bạn muốn chỉ lấy những bản ghi có sự tương ứng từ cả hai bảng.

Với các ví dụ trên, bạn có thể thấy LEFT JOIN rất mạnh mẽ trong việc xử lý các bài toán yêu cầu kết hợp dữ liệu từ nhiều bảng, ngay cả khi một số bảng không có thông tin khớp tương ứng.