Cum să folosești subquery-uri în SQL — WHERE, FROM, EXISTS
In this tutorial, you'll learn about Cum să folosești subquery. We cover key concepts, practical examples, and best practices.
Cum să folosești subquery-uri (subinterogări) în SQL în clauzele WHERE, FROM și EXISTS pentru a construi interogări avansate care depind de rezultatele altor interogări.
Problema
Unele întrebări despre date necesită interogări în mai mulți pași. De exemplu, "găsește produsele cu prețul peste media prețurilor" necesită mai întâi calculul mediei, apoi filtrarea. Fără subquery-uri, ai executa două interogări separate și ai combina rezultatele manual.
The Wrong Way
Executarea a două interogări separate și combinarea manuală:
# Pasul 1: calculează media
result = db.execute("SELECT AVG(price) FROM products")
avg_price = result[0][0]
# Pasul 2: filtrează
products = db.execute(
f"SELECT name, price FROM products WHERE price > {avg_price}"
)
Problema: Două călătorii la baza de date, cod fragil (concatenare SQL), și performanță inferioară unei singure interogări.
The Right Way
Folosește un subquery pentru a rezolva totul într-o singură interogare:
SELECT name, price
FROM products
WHERE price > (SELECT AVG(price) FROM products)
ORDER BY price DESC;
Output:
name | price
-------------+-------
Laptop | 3500.00
Monitor | 1200.00
Tablet | 800.00
Subquery-ul (SELECT AVG(price) FROM products) se execută o singură dată, iar rezultatul este folosit de interogarea principală.
Step-by-Step Fix
1. Subquery în WHERE
Folosește un subquery scalar (returnează o singură valoare):
SELECT employee_id, name, salary
FROM employees
WHERE salary > (SELECT AVG(salary) * 1.5 FROM employees);
2. Subquery cu IN
Returnează o listă de valori:
SELECT name
FROM customers
WHERE id IN (
SELECT customer_id
FROM orders
WHERE total > 1000
);
3. Subquery în FROM (tabelă derivată)
Tratează subquery-ul ca o tabelă temporară:
SELECT dept.avg_salary, e.name, e.salary
FROM employees e
JOIN (
SELECT department_id, AVG(salary) AS avg_salary
FROM employees
GROUP BY department_id
) dept ON e.department_id = dept.department_id
WHERE e.salary > dept.avg_salary;
4. Subquery cu EXISTS
Verifică existența înregistrărilor fără a returna date:
SELECT c.name
FROM customers c
WHERE EXISTS (
SELECT 1
FROM orders o
WHERE o.customer_id = c.id
AND o.total > 500
);
EXISTS este mai eficient decât IN când lista subquery-ului este mare.
5. Subquery corelat vs necorelat
Subquery necorelat (se execută o singură dată):
SELECT * FROM products
WHERE price > (SELECT AVG(price) FROM products);
Subquery corelat (se execută pentru fiecare rând exterior):
SELECT p1.name, p1.price
FROM products p1
WHERE p1.price > (
SELECT AVG(p2.price)
FROM products p2
WHERE p2.category_id = p1.category_id
);
Prevention Tips
- Preferă subquery-uri necorelate când este posibil — se execută o singură dată
- Folosește
EXISTSîn loc deINpentru seturi mari de date - Testează subquery-ul separat înainte de a-l îmbrica
- Adaugă indecși pe coloanele folosite în subquery-uri corelate
Greșeli comune cu subquery-uri
- Subquery returnează mai multe rânduri când se așteaptă unul — folosește
INsauANY - Subquery corelat fără index — se execută lent, de mii de ori
EXISTS (SELECT * ...)inutil —SELECT 1sauSELECT NULLeste suficient- Subquery în WHERE care poate fi rescris ca JOIN — JOIN este adesea mai eficient
- Subquery-uri imbricate prea adânc — greu de citit și întreținut
Exercițiu practic
Scrie o interogare care găsește angajații care câștigă mai mult decât media departamentului lor, folosind un subquery corelat.
Soluție:
SELECT e1.name, e1.salary, e1.department_id
FROM employees e1
WHERE e1.salary > (
SELECT AVG(e2.salary)
FROM employees e2
WHERE e2.department_id = e1.department_id
);
FAQ
Construit de dezvoltătorii Doda Browser, DodaZIP și Durga Antivirus Pro. Uneltele DodaTech se integrează nativ cu bazele de date pentru productivitate și securitate sporite.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro