Το COUNT(DISTINCT column) μετράει πόσες διαφορετικές τιμές έχει μια στήλη: μια τιμή που εμφανίζεται δέκα φορές μετράει μία φορά, και τα NULL δεν μετράνε καθόλου. Τα παραδείγματα δουλεύουν σε PostgreSQL, MySQL, SQLite και SQL Server.
Πώς χρησιμοποιείς το COUNT DISTINCT
Βάλε το DISTINCT μέσα στο COUNT(), μπροστά από τη στήλη ή την έκφραση που θέλεις να μετρήσεις:
COUNT(DISTINCT expression)
Το καταλαβαίνεις πιο εύκολα δίπλα στις άλλες δύο μορφές του COUNT. Το COUNT(*) μετράει γραμμές, το COUNT(column) μετράει γραμμές όπου η στήλη δεν είναι NULL, και το COUNT(DISTINCT column) μετράει τις διαφορετικές τιμές που δεν είναι NULL:
-- Input: orders
-- order_id | customer_id
-- ---------+------------
-- 1 | 1042
-- 2 | 1077
-- 3 | 1042
-- 4 | NULL
SELECT COUNT(*) AS all_rows,
COUNT(customer_id) AS with_customer,
COUNT(DISTINCT customer_id) AS customers
FROM orders;
-- Output:
-- all_rows | with_customer | customers
-- ---------+---------------+----------
-- 4 | 3 | 2
Τέσσερις παραγγελίες ήρθαν από δύο πελάτες: ο 1042 παρήγγειλε δύο φορές, και η παραγγελία 4 δεν έχει καθόλου πελάτη.
Κανόνες που πρέπει να ξέρεις
- Τα NULL δεν μετράνε. Αν μια τιμή που λείπει πρέπει να μετρήσει ως μία ακόμα, πρόσθεσέ την μόνος σου:
-- Input: the orders table above
SELECT COUNT(DISTINCT customer_id)
+ MAX(CASE WHEN customer_id IS NULL THEN 1 ELSE 0 END) AS customers_and_guests
FROM orders;
-- Output: 3
-
Η MySQL και ο SQL Server αγνοούν τα πεζά/κεφαλαία από προεπιλογή, οπότε μετράνε το
'SQL'και το'sql'ως μία τιμή. Μέτρα τοLOWER(tag)όταν τα πεζά/κεφαλαία δεν πρέπει να παίζουν ρόλο:
-- Input: tags
-- post_id | tag
-- --------+---------
-- 1 | SQL
-- 2 | sql
-- 3 | Postgres
SELECT COUNT(DISTINCT tag) FROM tags;
-- Output: 3 (2 in MySQL and SQL Server)
SELECT COUNT(DISTINCT LOWER(tag)) FROM tags;
-- Output: 2
-
Το DISTINCT δουλεύει και μέσα στα
SUMκαιAVG, αλλά αφαιρεί επαναλαμβανόμενες τιμές, όχι επαναλαμβανόμενες γραμμές. Δύο διαφορετικά προϊόντα με την ίδια τιμή προστίθενται μόνο μία φορά:
-- Input: order_lines
-- product | price
-- ---------+------
-- Pen | 2.00
-- Pencil | 2.00
-- Notebook | 5.00
SELECT SUM(price) AS total, SUM(DISTINCT price) AS distinct_total FROM order_lines;
-- Output:
-- total | distinct_total
-- ------+---------------
-- 9.00 | 7.00
Εναλλακτική σύνταξη
Το COUNT(DISTINCT ...) δέχεται μία στήλη. Για να μετρήσεις τους διαφορετικούς συνδυασμούς πολλών στηλών, μέτρα τις γραμμές ενός DISTINCT subquery. Η PostgreSQL και η MySQL έχουν επίσης συντομεύσεις:
-- Input: orders
-- order_id | customer_id | product_id
-- ---------+-------------+-----------
-- 1 | 1 | 23
-- 2 | 12 | 3
-- 3 | 1 | 23
-- 4 | 12 | 5
SELECT COUNT(*) FROM (SELECT DISTINCT customer_id, product_id FROM orders) AS pairs;
-- Output: 3
-- PostgreSQL
SELECT COUNT(DISTINCT (customer_id, product_id)) FROM orders;
-- Output: 3
-- MySQL
SELECT COUNT(DISTINCT customer_id, product_id) FROM orders;
-- Output: 3
Θα δεις επίσης τις στήλες να ενώνονται σε ένα string με το CONCAT(). Χρειάζεται διαχωριστικό: χωρίς αυτό, ο πελάτης 1 με το προϊόν 23 και ο πελάτης 12 με το προϊόν 3 γίνονται και οι δύο '123':
-- Input: the orders table above
SELECT COUNT(DISTINCT CONCAT(customer_id, product_id)) FROM orders;
-- Output: 2
SELECT COUNT(DISTINCT CONCAT(customer_id, '_', product_id)) FROM orders;
-- Output: 3
Μια ακριβής μέτρηση διαφορετικών τιμών πρέπει να ταξινομήσει ή να κάνει hash κάθε τιμή, κάτι που γίνεται αργό σε πολύ μεγάλους πίνακες. Ο SQL Server έχει το APPROX_COUNT_DISTINCT(), που είναι πιο γρήγορο και μένει εντός 2% από την ακριβή μέτρηση στο 97% των περιπτώσεων:
-- SQL Server
-- Input: the orders table above
SELECT APPROX_COUNT_DISTINCT(customer_id) AS customers FROM orders;
-- Output: 2
Πότε να χρησιμοποιείς το COUNT DISTINCT;
Χρησιμοποίησε το COUNT DISTINCT όταν η ερώτηση είναι «πόσα διαφορετικά …;» και όχι «πόσες γραμμές;». Οι περισσότερες τέτοιες ερωτήσεις ανήκουν σε μία από αυτές τις τέσσερις.
Μέτρα μοναδικούς επισκέπτες, πελάτες ή προϊόντα
Ένα log επισκέψεων, παραγγελιών ή πωλήσεων καταγράφει τον ίδιο επισκέπτη, πελάτη ή προϊόν ξανά και ξανά. Το COUNT DISTINCT στο ID του μετατρέπει αυτές τις γραμμές σε καταμέτρηση.
Μέτρα μοναδικές τιμές σε κάθε ομάδα
Πρόσθεσε GROUP BY και παίρνεις μία μέτρηση διαφορετικών τιμών ανά ομάδα: διαφορετικούς φοιτητές ανά μάθημα, διαφορετικά προϊόντα ανά πωλητή, διαφορετικούς πελάτες ανά μήνα.
Μέτρα μοναδικούς συνδυασμούς στηλών
Μερικές φορές δύο γραμμές είναι «ίδιες» μόνο όταν ταιριάζουν δύο στήλες μαζί: ο ίδιος χρήστης με τον ίδιο τύπο προβλήματος ή η ίδια διαδρομή ανάμεσα σε δύο αεροδρόμια. Μέτρα τους συνδυασμούς με μία από τις μορφές πολλών στηλών στην ενότητα «Εναλλακτική σύνταξη».
Μέτρα μοναδικές τιμές που πληρούν μια συνθήκη
Βάλε μια έκφραση CASE μέσα στο COUNT(DISTINCT ...) για να μετρήσεις μόνο κάποιες από τις γραμμές. Το CASE επιστρέφει NULL για τις γραμμές που δεν θέλεις, και τα NULL δεν μετράνε, οπότε ένα query μπορεί να επιστρέψει πολλές φιλτραρισμένες μετρήσεις δίπλα δίπλα.
Πραγματικά παραδείγματα του COUNT DISTINCT
Μηνιαίοι ενεργοί χρήστες
Μέτρα τους χρήστες που έκαναν οτιδήποτε τον Σεπτέμβριο, όσες φορές κι αν επέστρεψαν:
-- Input: events
-- event_id | user_id | event_date
-- ---------+---------+-----------
-- 1 | 301 | 2026-08-30
-- 2 | 302 | 2026-09-02
-- 3 | 302 | 2026-09-15
-- 4 | 305 | 2026-09-21
-- 5 | 302 | 2026-10-01
SELECT COUNT(DISTINCT user_id) AS active_users
FROM events
WHERE event_date >= '2026-09-01' AND event_date < '2026-10-01';
-- Output: 2
Προϊόντα που πούλησε κάθε πωλητής
Το COUNT(*) δίνει τον αριθμό πωλήσεων κάθε πωλητή, και το COUNT(DISTINCT product) πόσα διαφορετικά προϊόντα κάλυψαν αυτές οι πωλήσεις:
-- Input: sales
-- vendor | product | color
-- -----------+----------+------
-- Acme | Mug | Red
-- Acme | Mug | Blue
-- Acme | Mug | Red
-- Acme | Tote Bag | Red
-- Brightside | Notebook | Black
SELECT vendor, COUNT(*) AS sales, COUNT(DISTINCT product) AS products
FROM sales
GROUP BY vendor;
-- Output:
-- vendor | sales | products
-- -----------+-------+---------
-- Acme | 4 | 2
-- Brightside | 1 | 1
Διαδρομές μιας αεροπορικής
Μια διαδρομή είναι μια αφετηρία και ένας προορισμός μαζί. Δύο πτήσεις από LHR προς JFK είναι μία διαδρομή, αλλά από JFK προς LHR είναι άλλη:
-- Input: flights
-- flight_no | origin | destination
-- ----------+--------+------------
-- 101 | LHR | JFK
-- 105 | LHR | JFK
-- 102 | JFK | LHR
-- 301 | LHR | LAX
SELECT COUNT(*) AS routes
FROM (SELECT DISTINCT origin, destination FROM flights) AS r;
-- Output: 3
Πελάτες ανά τιμή αγορών
Μέτρα τους πελάτες που αγόρασαν τα προϊόντα 100 έως 200 και μετά χώρισέ τους με βάση την τιμή των παραγγελιών τους. Ο πελάτης 7 έκανε δύο φθηνές παραγγελίες αλλά μετράει μία φορά, και το προϊόν του πελάτη 15 είναι εκτός εύρους:
-- Input: orders
-- order_id | customer_id | product_id | price
-- ---------+-------------+------------+-------
-- 1 | 7 | 105 | 25.00
-- 2 | 7 | 142 | 40.00
-- 3 | 9 | 150 | 120.00
-- 4 | 12 | 188 | 310.00
-- 5 | 15 | 260 | 30.00
SELECT
COUNT(DISTINCT customer_id) AS customers,
COUNT(DISTINCT CASE WHEN price BETWEEN 1 AND 50 THEN customer_id END) AS low_spenders,
COUNT(DISTINCT CASE WHEN price BETWEEN 51 AND 150 THEN customer_id END) AS mid_spenders,
COUNT(DISTINCT CASE WHEN price > 150 THEN customer_id END) AS high_spenders
FROM orders
WHERE product_id BETWEEN 100 AND 200;
-- Output:
-- customers | low_spenders | mid_spenders | high_spenders
-- ----------+--------------+--------------+--------------
-- 3 | 1 | 1 | 1
Ένας πελάτης με παραγγελίες σε δύο κλίμακες τιμών μετριέται και στις δύο.
Περισσότερα για το COUNT DISTINCT
Σε αυτό το blog:
-
Οδηγός για το SQL GROUP BY:
COUNT,SUMκαιAVGγια κάθε ομάδα - Οδηγός εύρεσης διπλοτύπων σε SQL: βρες τις τιμές που εμφανίζονται πάνω από μία φορά
- Οδηγός αφαίρεσης διπλοτύπων σε SQL: διάγραψε τα επιπλέον αντίγραφα
- Οδηγός για το SQL CASE: οι συνθήκες πίσω από τις μετρήσεις υπό όρους
-
Having vs Where στην SQL: φιλτράρισμα σε μια μέτρηση με
HAVING - SQL cheat sheet: aggregates και η υπόλοιπη SQL σε μία σελίδα
Επίσημη τεκμηρίωση:
- PostgreSQL: aggregate expressions
- MySQL: COUNT(DISTINCT)
- SQLite: count()
- SQL Server: COUNT και APPROX_COUNT_DISTINCT
Το Beekeeper Studio είναι ένα δωρεάν & open source GUI για βάσεις δεδομένων
Το καλύτερο εργαλείο για SQL queries & επεξεργασία που έχω χρησιμοποιήσει ποτέ. Μου δίνει ό,τι χρειάζομαι για να διαχειρίζομαι τη βάση δεδομένων μου. - ⭐⭐⭐⭐⭐ Mit
Το Beekeeper Studio είναι γρήγορο, εύχρηστο και κατανοητό με την πρώτη ματιά. Υποστηρίζει πάρα πολλές βάσεις δεδομένων και δουλεύει άψογα σε Windows, Mac και Linux.
Τι λένε οι χρήστες για το Beekeeper Studio
"Το Beekeeper Studio αντικατέστησε πλήρως την παλιά μου ροή εργασίας SQL. Είναι γρήγορο, εύχρηστο και κάνει τη δουλειά με βάσεις δεδομένων ξανά απολαυστική."
"Έχω δοκιμάσει πολλά GUI για βάσεις δεδομένων, αλλά το Beekeeper βρίσκει την τέλεια ισορροπία ανάμεσα σε λειτουργίες και απλότητα. Απλά δουλεύει."