VieTopik
Tiếng HànTiếng AnhIT
  • Góc học tập
Tải app
  • Thư viện
  • Luyện thi
  • Cẩm nang
  • Góc học tập
SQL với OracleNối bảng
Bài 10/16
5 phút

Subquery

Nội dung bài · 5 mục
  1. 1.Khái niệm
  2. 2.Ví dụ
  3. 3.Thử ngay
  4. 4.Lỗi hay gặp
  5. 5.Tóm tắt

Không thể viết WHERE price > AVG(price), vì hàm tổng hợp không dùng được trong WHERE (bài GROUP BY và HAVING). Phải tính giá trung bình trước rồi mới lọc; subquery làm việc này trong một câu.

Khái niệm

🪆 Subquery: câu SELECT đặt bên trong một câu SQL khác, kết quả của nó được dùng như một giá trị hoặc một danh sách.

Ví dụ

SELECT name, price
FROM products
WHERE price > (SELECT AVG(price) FROM products)
ORDER BY price;
  • Câu trong ngoặc chạy trước, trả về một con số: giá trung bình là 164800.
  • Câu bên ngoài dùng con số đó để lọc, ra Balo và Máy tính.
  • Subquery trả về một giá trị thì so sánh bằng =, >, <.
  • Subquery trả về nhiều dòng thì dùng IN.

Thử ngay

Khách nào có ít nhất một đơn đã thanh toán?

SELECT name
FROM customers
WHERE customer_id IN (
  SELECT customer_id FROM orders WHERE status = 'PAID'
)
ORDER BY customer_id;

Đoán trước khi chạy: An có một đơn PAID và một đơn NEW, Chi chỉ có đơn CANCELLED. Ai nằm trong kết quả?

Xem kết quả
NAME
An
Bình

Subquery trả về danh sách mã khách có đơn PAID: 1 và 2. An có ít nhất một đơn PAID nên được giữ. Chi không có đơn nào như vậy.

Lỗi hay gặp

So sánh bằng = với subquery trả về nhiều dòng. Oracle báo ORA-01427: single-row subquery returns more than one row.

-- SAI — lỗi: có hai khách ở Hà Nội
SELECT order_id FROM orders
WHERE customer_id = (
  SELECT customer_id FROM customers
  WHERE city = 'Hà Nội'
);
-- ĐÚNG — nhiều giá trị thì dùng IN
SELECT order_id FROM orders
WHERE customer_id IN (
  SELECT customer_id FROM customers
  WHERE city = 'Hà Nội'
);

NOT IN với danh sách có NULL. Email của Chi là NULL. Chỉ cần danh sách có một giá trị NULL là NOT IN không trả về dòng nào.

-- SAI — không trả về dòng nào
SELECT name FROM customers
WHERE email NOT IN (
  SELECT email FROM customers WHERE city = 'Hà Nội'
);
-- ĐÚNG — loại NULL khỏi danh sách
SELECT name FROM customers
WHERE email NOT IN (
  SELECT email FROM customers
  WHERE city = 'Hà Nội' AND email IS NOT NULL
);

Tóm tắt

  • Subquery là câu SELECT lồng trong câu khác, chạy trước để lấy giá trị.
  • Trả về một giá trị thì dùng =, >, <. Trả về nhiều dòng thì dùng IN.
  • Dùng subquery để lọc theo giá trị tổng hợp như trung bình.
  • Cẩn thận NOT IN khi danh sách có thể chứa NULL.

Tự kiểm tra

0/3 câu
Câu 1

Tìm đơn hàng của khách tên An. Câu nào đúng, biết có thể có nhiều khách trùng tên An?

Câu 2

Tìm sản phẩm có giá cao nhất. Câu nào đúng?

Câu 3

WHERE id NOT IN (1, 2, NULL) trả về bao nhiêu dòng?

LEFT JOININSERT, UPDATE, DELETE

Nội dung bài

  1. 1.Khái niệm
  2. 2.Ví dụ
  3. 3.Thử ngay
  4. 4.Lỗi hay gặp
  5. 5.Tóm tắt