Clauza WITH (Common Table Expressions – CTE) în MySQL

Citirea datelor MySQL 8.0+

Ghid complet pentru clauza WITH în MySQL 8: structurarea interogărilor complexe prin tabele temporare numite în memorie, lizibilitate crescută și reutilizarea subinterogărilor.

Sintaxă
WITH vanzari_mari AS (SELECT * FROM vanzari WHERE total > 1000) SELECT * FROM vanzari_mari ...

Clauza WITH (cunoscută drept Common Table Expression sau CTE) permite crearea unor seturi de rezultate temporare cu nume, valabile exclusiv pe durata execuției unei singure interogări (SELECT, INSERT, UPDATE sau DELETE). Introdusă în MySQL 8.0, clauza WITH înlocuiește subinterogările imbricate greu de citit și permite reutilizarea aceluiași bloc de date în mai multe locuri ale aceleiași interogări.

Exemplu practic: Calculul comenzilor peste medie folosind CTE
-- 1. Definim un CTE care calculează valoarea medie a vânzărilor
WITH StatisticiComenzi AS (
    SELECT 
        AVG(total) AS valoare_medie,
        MAX(total) AS valoare_maxima
    FROM comenzi
),
-- 2. Definim un al doilea CTE care extrage clienții VIP
ClientiTop AS (
    SELECT client_id, SUM(total) AS total_cheltuit
    FROM comenzi
    GROUP BY client_id
    HAVING total_cheltuit > 5000
)
-- 3. Interogarea principală care folosește ambele CTE-uri:
SELECT 
    c.id, 
    c.numar_comanda, 
    c.total,
    s.valoare_medie,
    ROUND(c.total - s.valoare_medie, 2) AS diferenta_fata_de_medie
FROM comenzi c
JOIN ClientiTop ct ON c.client_id = ct.client_id
CROSS JOIN StatisticiComenzi s
WHERE c.total > s.valoare_medie
ORDER BY c.total DESC;

Avantaje Majore față de Subinterogările Tradiționale

  • Lizibilitate liniară (Top-Down): Logica se citește de sus în jos în mod natural, eliminând subinterogările adânc parantezate din clauza FROM.
  • Reutilizare în aceeași interogare: Poți face referire la același CTE de mai multe ori (de exemplu, un JOIN între două instanțe ale aceluiași CTE).
  • Optimizare internă: Optimizatorul MySQL poate decide să materializeze CTE-ul într-un tabel temporar în memorie sau să îl execute inline dacă este mai rapid.