Skip to content

Cum să folosești subquery-uri în SQL — WHERE, FROM, EXISTS

DodaTech Updated 2025-01-15 3 min read

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 de IN pentru 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

  1. Subquery returnează mai multe rânduri când se așteaptă unul — folosește IN sau ANY
  2. Subquery corelat fără index — se execută lent, de mii de ori
  3. EXISTS (SELECT * ...) inutil — SELECT 1 sau SELECT NULL este suficient
  4. Subquery în WHERE care poate fi rescris ca JOIN — JOIN este adesea mai eficient
  5. 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

### Când ar trebui să folosesc EXISTS în loc de IN?

EXISTS este mai rapid când subquery-ul returnează un set mare de rezultate, pentru că se oprește la prima potrivire. IN este mai lizibil pentru seturi mici.

Ce este un subquery corelat?

Un subquery care face referire la coloane din interogarea exterioară. Se execută o dată pentru fiecare rând al interogării exterioare, motiv pentru care poate fi lent.

Pot folosi subquery-uri în SELECT?

Da, subquery-urile scalare pot fi folosite în SELECT: SELECT name, (SELECT AVG(price) FROM products) AS avg_price FROM products;

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