🧚 Άκου! Το Beekeeper Studio είναι ένα γρήγορο, σύγχρονο και open source GUI για βάσεις δεδομένων Λήψη
7 Ιανουαρίου 2026 Από τον Lucas Gray

Ένα subquery είναι ένα query μέσα σε άλλο query. Ένα CTE (common table expression) είναι το ίδιο εσωτερικό query, μεταφερμένο στην αρχή της εντολής με WITH και με ένα όνομα, ώστε ένα μεγάλο query να διαβάζεται σαν σειρά βημάτων. Τα παραδείγματα δουλεύουν σε PostgreSQL, MySQL, SQLite και SQL Server.

Πώς να χρησιμοποιήσεις CTE και subquery

Ένα subquery μπαίνει εκεί όπου χρησιμοποιείται: στο FROM λειτουργεί σαν πίνακας, ενώ στο WHERE ή στο SELECT δίνει μια τιμή ή μια λίστα. Ένα CTE ορίζεται πρώτα και μετά το query που ακολουθεί το χρησιμοποιεί σαν πίνακα:

-- Subquery: written where it's used
SELECT columns FROM (SELECT ...) AS name;

-- CTE: named first, then used like a table
WITH name AS (SELECT ...)
SELECT columns FROM name;
SELECT n * 2 AS doubled FROM (SELECT 21 AS n) AS numbers;
-- Output: 42

WITH numbers AS (SELECT 21 AS n)
SELECT n * 2 AS doubled FROM numbers;
-- Output: 42

Σε έναν πραγματικό πίνακα, οι δύο μορφές επιστρέφουν τις ίδιες γραμμές. Δες ένα φίλτρο γραμμένο και με τους δύο τρόπους:

-- Input: people
-- first_name | last_name | job      | favorite_food
-- -----------+-----------+----------+--------------
-- Matthew    | Ortiz     | Chef     | cheese
-- Matt       | Novak     | Pilot    | pizza
-- Mattie     | Brooks    | Engineer | cheese
-- Priya      | Nair      | Teacher  | cheese

-- Subquery
SELECT *
FROM (SELECT first_name, last_name, job FROM people WHERE favorite_food = 'cheese') AS cheese_lovers
WHERE first_name LIKE 'Matt%';

-- CTE
WITH cheese_lovers AS (
  SELECT first_name, last_name, job FROM people WHERE favorite_food = 'cheese'
)
SELECT * FROM cheese_lovers
WHERE first_name LIKE 'Matt%';

-- Output of both:
-- first_name | last_name | job
-- -----------+-----------+---------
-- Matthew    | Ortiz     | Chef
-- Mattie     | Brooks    | Engineer

Κανόνες που πρέπει να ξέρεις

  • Ένα CTE ισχύει μόνο για μία εντολή. Το query αμέσως μετά το WITH μπορεί να το χρησιμοποιήσει· η επόμενη εντολή όχι. Για να κρατήσεις ένα αποτέλεσμα για πολλά queries, χρησιμοποίησε προσωρινό πίνακα ή view.
  • Δώσε όνομα σε ένα subquery μέσα στο FROM, όπως το AS numbers παραπάνω. Η MySQL και ο SQL Server το απορρίπτουν χωρίς όνομα.
  • Ένα subquery που χρησιμοποιείται ως μία τιμή πρέπει να επιστρέφει μία γραμμή:
SELECT (SELECT 1 UNION ALL SELECT 2) AS n;
-- ERROR: more than one row returned by a subquery used as an expression
-- (SQLite doesn't complain: it quietly uses the first row, 1)
  • Η ταχύτητα συνήθως είναι η ίδια. Οι βάσεις δεδομένων γενικά σχεδιάζουν ένα CTE που χρησιμοποιείται μία φορά όπως και το αντίστοιχο subquery, οπότε διάλεξε ό,τι διαβάζεται καλύτερα.

Εναλλακτική σύνταξη

Ένα CTE που αναφέρεται στον εαυτό του (δες παρακάτω) γράφεται WITH RECURSIVE:

-- In SQL Server, leave out RECURSIVE
WITH RECURSIVE counter AS (
  SELECT 1 AS n
  UNION ALL
  SELECT n + 1 FROM counter WHERE n < 3
)
SELECT n FROM counter;

-- Output:
-- n
-- -
-- 1
-- 2
-- 3

Στον SQL Server, η εντολή πριν από ένα WITH πρέπει να τελειώνει με ερωτηματικό, γι' αυτό ο κώδικας T-SQL συχνά ξεκινά ένα CTE με ;WITH.

Πότε να χρησιμοποιήσεις CTE αντί για subquery;

Ένα subquery αρκεί για ένα μικρό βήμα. Πέρνα σε CTE όταν το query έχει πολλά βήματα, χρειάζεται το ίδιο αποτέλεσμα δύο φορές ή πρέπει να αναφέρεται στον εαυτό του.

Φιλτράρισμα με βάση μία υπολογισμένη τιμή

Όταν το εσωτερικό query παράγει απλώς μια τιμή ή μια λίστα για σύγκριση, όπως το μέσο σύνολο παραγγελίας, ένα subquery στο WHERE είναι ο πιο σύντομος τρόπος. Θα δούλευε και ένα CTE, αλλά προσθέτει ένα όνομα που δεν χρειάζεται κανείς.

Σπάσε ένα μεγάλο query σε βήματα με όνομα

Όταν ένα query έχει στάδια (σύνολο ανά πελάτη, μετά οι κορυφαίοι, μετά η τελική λίστα), δώσε όνομα σε κάθε στάδιο. Γράψε πολλά CTE μετά από ένα WITH, χωρισμένα με κόμματα: το καθένα μπορεί να χρησιμοποιεί τα προηγούμενα, και το query διαβάζεται από πάνω προς τα κάτω αντί από μέσα προς τα έξω.

Χρησιμοποίησε το ίδιο αποτέλεσμα πολλές φορές

Μια εντολή μπορεί να αναφέρεται σε ένα CTE όσες φορές θέλει, οπότε ένα αποτέλεσμα που χρειάζεσαι δύο φορές (μια λίστα συνόλων και ο μέσος όρος τους, ή κάθε σύνολο και το γενικό σύνολο) γράφεται μία φορά. Με subqueries θα αντέγραφες ολόκληρο το εσωτερικό query.

Διάσχιση ιεραρχίας

Μόνο ένα CTE μπορεί να αναφέρεται στον εαυτό του. Ένα recursive CTE ξεκινά από κάποιες γραμμές και συνεχίζει να κάνει join με τον πίνακα μέχρι να μην εμφανίζονται νέες γραμμές. Έτσι διασχίζεις ένα οργανόγραμμα ή ένα δέντρο κατηγοριών, ή παράγεις μια σειρά αριθμών ή ημερομηνιών.

Πραγματικά παραδείγματα CTE και subquery

Προϊόντα με τιμή πάνω από τον μέσο όρο της κατηγορίας τους

Το subquery αναφέρεται στο p.category του εξωτερικού query, οπότε υπολογίζεται για την κατηγορία κάθε προϊόντος (correlated subquery):

-- Input: products
-- name          | category  | price
-- --------------+-----------+-------
-- Desk Lamp     | Lighting  | 24.99
-- Floor Lamp    | Lighting  | 89.00
-- Office Chair  | Furniture | 149.00
-- Standing Desk | Furniture | 399.00
-- Bookshelf     | Furniture | 120.00

SELECT name, category, price
FROM products p
WHERE price > (
  SELECT AVG(price) FROM products WHERE category = p.category
)
ORDER BY category, name;

-- Output:
-- name          | category  | price
-- --------------+-----------+-------
-- Standing Desk | Furniture | 399.00
-- Floor Lamp    | Lighting  | 89.00

Το πιο δημοφιλές προϊόν κάθε κατηγορίας

Τρία βήματα, το καθένα με όνομα: άθροισε τις μονάδες ανά προϊόν, κατάταξε τα προϊόντα σε κάθε κατηγορία και κράτα το πρώτο:

-- Input: sales
-- id | product      | category  | units
-- ---+--------------+-----------+------
-- 1  | Desk Lamp    | Lighting  | 3
-- 2  | Floor Lamp   | Lighting  | 5
-- 3  | Desk Lamp    | Lighting  | 4
-- 4  | Office Chair | Furniture | 2
-- 5  | Bookshelf    | Furniture | 6

WITH product_totals AS (
  SELECT category, product, SUM(units) AS units
  FROM sales
  GROUP BY category, product
),
ranked AS (
  SELECT category, product, units,
         RANK() OVER (PARTITION BY category ORDER BY units DESC) AS place
  FROM product_totals
)
SELECT category, product, units
FROM ranked
WHERE place = 1
ORDER BY category;

-- Output:
-- category  | product   | units
-- ----------+-----------+------
-- Furniture | Bookshelf | 6
-- Lighting  | Desk Lamp | 7

Το μερίδιο πωλήσεων κάθε περιοχής

Το region_totals χρησιμοποιείται δύο φορές: μία για τις γραμμές και μία μέσα σε ένα subquery για το γενικό σύνολο:

-- Input: orders
-- id | region | amount
-- ---+--------+--------
-- 1  | North  | 1200.00
-- 2  | South  | 450.00
-- 3  | North  | 300.00
-- 4  | West   | 800.00
-- 5  | South  | 250.00

WITH region_totals AS (
  SELECT region, SUM(amount) AS total
  FROM orders
  GROUP BY region
)
SELECT
  region,
  total,
  ROUND(100.0 * total / (SELECT SUM(total) FROM region_totals), 1) AS pct_of_sales
FROM region_totals
ORDER BY total DESC;

-- Output:
-- region | total   | pct_of_sales
-- -------+---------+-------------
-- North  | 1500.00 | 50.0
-- West   | 800.00  | 26.7
-- South  | 700.00  | 23.3

Με subqueries, το query με GROUP BY θα εμφανιζόταν δύο φορές.

Η αλυσίδα προϊσταμένων ενός υπαλλήλου

Ξεκίνα από έναν υπάλληλο και ακολούθησε το manager_id προς τα πάνω μέχρι να τελειώσει:

-- Input: employees
-- id | name      | manager_id
-- ---+-----------+-----------
-- 1  | Maya Chen | NULL
-- 2  | Sam Ortiz | 1
-- 3  | Jo Kim    | 2
-- 4  | Lee Ross  | 2
-- 5  | Ana Diaz  | 1

-- In SQL Server, leave out RECURSIVE
WITH RECURSIVE chain AS (
  SELECT id, name, manager_id, 0 AS level
  FROM employees
  WHERE name = 'Jo Kim'
  UNION ALL
  SELECT e.id, e.name, e.manager_id, chain.level + 1
  FROM employees e
  JOIN chain ON e.id = chain.manager_id
)
SELECT level, name FROM chain ORDER BY level;

-- Output:
-- level | name
-- ------+----------
-- 0     | Jo Kim
-- 1     | Sam Ortiz
-- 2     | Maya Chen

Περισσότερα για CTE και subquery

Σε αυτό το blog:

Επίσημη τεκμηρίωση:

Το Beekeeper Studio είναι ένα δωρεάν & open source GUI για βάσεις δεδομένων

Το καλύτερο εργαλείο για SQL queries & επεξεργασία που έχω χρησιμοποιήσει ποτέ. Μου δίνει ό,τι χρειάζομαι για να διαχειρίζομαι τη βάση δεδομένων μου. - ⭐⭐⭐⭐⭐ Mit

Το Beekeeper Studio είναι γρήγορο, εύχρηστο και κατανοητό με την πρώτη ματιά. Υποστηρίζει πάρα πολλές βάσεις δεδομένων και δουλεύει άψογα σε Windows, Mac και Linux.

Η έκδοση του Beekeeper για Linux έχει 100% όλες τις λειτουργίες, χωρίς εκπτώσεις και χωρίς συμβιβασμούς.

Τι λένε οι χρήστες για το Beekeeper Studio

★★★★★
«Το Beekeeper Studio αντικατέστησε εντελώς την παλιά μου ροή εργασίας με SQL. Είναι γρήγορο, εύχρηστο και κάνει τη δουλειά με βάσεις δεδομένων ξανά ευχάριστη.»
— Alex K., Database Developer
★★★★★
«Έχω δοκιμάσει πολλά GUI για βάσεις δεδομένων, αλλά το Beekeeper πετυχαίνει την τέλεια ισορροπία ανάμεσα σε δυνατότητες και απλότητα. Απλώς δουλεύει.»
— Sarah M., Full Stack Engineer

Έτοιμος να βελτιώσεις τη ροή εργασίας σου με SQL;

download Δωρεάν λήψη