MySQL ΟΜΑΔΑ ΑΝΑ και ΕΧΕΙ Ρήτρα με Παραδείγματα
⚡ Έξυπνη Σύνοψη
Οι όροι SQL GROUP BY και HAVING μετατρέπουν τις λεπτομερείς γραμμές σε συνοπτικές αναφορές. Η συνάρτηση GROUP BY συμπτύσσει τις γραμμές που μοιράζονται τις ίδιες τιμές σε μία γραμμή ανά ομάδα, ενώ η συνάρτηση HAVING φιλτράρει αυτές τις ομάδες μετά την εφαρμογή συναρτήσεων συγκέντρωσης όπως η COUNT.
Τι είναι η ρήτρα SQL GROUP BY;
Ο όρος GROUP BY είναι μια εντολή SQL που χρησιμοποιείται ομαδοποιήστε σειρές που έχουν τις ίδιες τιμέςΕίναι γραμμένο μέσα στην πρόταση SELECT και χρησιμοποιείται συνήθως μαζί με συναρτήσεις συγκέντρωσης για την παραγωγή συνοπτικών αναφορών από τη βάση δεδομένων.
Αυτό ακριβώς κάνει: συνοψίζει τα δεδομένα που διατηρούνται στη βάση δεδομένων. Τα ερωτήματα που περιέχουν τον όρο GROUP BY ονομάζονται ομαδοποιημένα ερωτήματα και επιστρέφουν μία μόνο γραμμή για κάθε ομαδοποιημένο στοιχείο.
SQL GROUP BY Syntax
Τώρα που ο σκοπός της ρήτρας είναι σαφής, εξετάστε τη σύνταξη ενός βασικού ομαδοποιημένου ερωτήματος.
SELECT statements... GROUP BY column_name1[, column_name2, ...] [HAVING condition];
ΕΔΩ
- "Δηλώσεις SELECT…«είναι το πρότυπο» SQL SELECT ερώτημα εντολής.
- "GROUP BY στήλη_όνομα1είναι η πρόταση που εκτελεί την ομάδαping με βάση το column_name1.
- "[, όνομα_στήλης2, …]Το "" είναι προαιρετικό και αντιπροσωπεύει άλλα ονόματα στηλών όταν η ομάδαping γίνεται σε περισσότερες από μία στήλες.
- "[ΈΧΟΝΤΑΣ μια κατάσταση]Το "" είναι προαιρετικό και χρησιμοποιείται για τον περιορισμό των γραμμών που επηρεάζονται από την ρήτρα GROUP BY. Είναι παρόμοιο με το ΟΤΙ ρήτρα, εκτός από το ότι εφαρμόζεται μετά την αρμόστοκηping.
Grouping Χρήση μίας στήλης
Ο πιο γρήγορος τρόπος για να δείτε το αποτέλεσμα της ρήτρας SQL GROUP BY είναι να συγκρίνετε ένα μη ομαδοποιημένο ερώτημα με ένα ομαδοποιημένο. Ξεκινήστε με ένα απλό ερώτημα που επιστρέφει κάθε καταχώρηση φύλου στον πίνακα μελών.
SELECT `gender` FROM `members`;
| των δύο φύλων |
|---|
| Γυναίκα |
| Γυναίκα |
| Άντρας |
| Γυναίκα |
| Άντρας |
| Άντρας |
| Άντρας |
| Άντρας |
| Άντρας |
Επιστρέφονται εννέα γραμμές και κάθε τιμή επαναλαμβάνεται. Ας υποθέσουμε ότι θέλουμε τις μοναδικές τιμές για το φύλο. Το παρακάτω ερώτημα προσθέτει τον όρο GROUP BY.
SELECT `gender` FROM `members` GROUP BY `gender`;
Εκτέλεση του παραπάνω σεναρίου στο MySQL Πάγκος εργασίας ενάντια στο myflixdb μας δίνει τα ακόλουθα αποτελέσματα.
| των δύο φύλων |
|---|
| Γυναίκα |
| Άντρας |
Σημειώστε ότι έχουν επιστραφεί μόνο δύο γραμμές, επειδή ο πίνακας περιέχει μόνο δύο τύπους φύλου. Η ρήτρα GROUP BY ομαδοποίησε όλα τα μέλη "Άνδρες" και επέστρεψε μία γραμμή για αυτά, και έκανε το ίδιο με τα μέλη "Γυναίκες".
Grouping Χρήση πολλαπλών στηλών
Grouping σε μία στήλη είναι συχνά πολύ χονδρική για μια πραγματική αναφορά. Η συνάρτηση GROUP BY δέχεται μια λίστα στηλών διαχωρισμένων με κόμμα και ο συνδυασμός των τιμών τους ορίζει κάθε ομάδα.
Ας υποθέσουμε ότι θέλουμε μια λίστα με τιμές category_id ταινιών και τα αντίστοιχα έτη κυκλοφορίας των ταινιών. Παρατηρήστε πρώτα το αποτέλεσμα αυτού του απλού ερωτήματος.
SELECT `category_id`, `year_released` FROM `movies`;
| κατηγορία_αναγνωριστικό | έτος_κυκλοφόρησε |
|---|---|
| 1 | 2011 |
| 2 | 2008 |
| Τιμή NULL | 2008 |
| Τιμή NULL | 2010 |
| 8 | 2007 |
| 6 | 2007 |
| 6 | 2007 |
| 8 | 2005 |
| Τιμή NULL | 2012 |
| 7 | 1920 |
| 8 | Τιμή NULL |
| 8 | 1920 |
Οι επισημασμένες γραμμές δείχνουν ότι το αποτέλεσμα περιέχει διπλότυπα. Η εκτέλεση του ίδιου ερωτήματος με GROUP BY τα καταργεί.
SELECT `category_id`, `year_released` FROM `movies` GROUP BY `category_id`, `year_released`;
Εκτέλεση του παραπάνω σεναρίου στο MySQL Το Workbench σε σχέση με το myflixdb μας δίνει τα ακόλουθα αποτελέσματα που φαίνονται παρακάτω.
| κατηγορία_αναγνωριστικό | έτος_κυκλοφόρησε |
|---|---|
| Τιμή NULL | 2008 |
| Τιμή NULL | 2010 |
| Τιμή NULL | 2012 |
| 1 | 2011 |
| 2 | 2008 |
| 6 | 2007 |
| 7 | 1920 |
| 8 | 1920 |
| 8 | 2005 |
| 8 | 2007 |
Η ρήτρα GROUP BY λειτουργεί τόσο στο category_id όσο και στο year_released για να προσδιορίσει μοναδικός γραμμές. Οι δύο διπλότυπες γραμμές για την κατηγορία 6 το 2007 συμπτύχθηκαν σε μία.
Κανόνας: Εάν το αναγνωριστικό κατηγορίας είναι το ίδιο αλλά το έτος κυκλοφορίας είναι διαφορετικό, η γραμμή αντιμετωπίζεται ως μοναδική. Εάν το αναγνωριστικό κατηγορίας και το έτος κυκλοφορίας είναι τα ίδια για περισσότερες από μία γραμμές, οι γραμμές είναι διπλότυπες και εμφανίζεται μόνο μία από αυτές.
Grouping και Συναρτήσεις Συγκεντρώσεων
Η αφαίρεση διπλότυπων είναι χρήσιμη, αλλά η πραγματική δύναμη της ομάδαςping εμφανίζεται όταν συνδυάζεται με αθροιστικές συναρτήσειςΜια συνάρτηση συγκεντρωτικών αποτελεσμάτων υπολογίζει μία τιμή για κάθε ομάδα: η συνάρτηση COUNT μετράει γραμμές, η συνάρτηση SUM προσθέτει τιμές και AVGΤα , MIN και MAX περιγράφουν την εξάπλωση.
Ας υποθέσουμε ότι θέλουμε τον συνολικό αριθμό ανδρών και γυναικών μελών στη βάση δεδομένων. Το παρακάτω σενάριο το κάνει αυτό.
SELECT `gender`, COUNT(`membership_number`) FROM `members` GROUP BY `gender`;
Εκτέλεση του παραπάνω σεναρίου στο MySQL Το Workbench σε σχέση με το myflixdb μας δίνει τα ακόλουθα αποτελέσματα.
| των δύο φύλων | COUNT(`αριθμός_μέλους`) |
|---|---|
| Γυναίκα | 3 |
| Άντρας | 6 |
Οι γραμμές ομαδοποιούνται με βάση κάθε μοναδική τιμή φύλου και ο αριθμός των γραμμών μέσα σε κάθε ομάδα μετριέται από τη συνάρτηση συγκέντρωσης COUNT. Οι εννέα εγγραφές μελών συμπτύσσονται σε δύο γραμμές σύνοψης.
Περιορισμός αποτελεσμάτων ερωτήματος χρησιμοποιώντας την ρήτρα HAVING
GroupingΤα s δεν είναι πάντα απαραίτητα για κάθε γραμμή σε έναν πίνακα. Μερικές φορές η αναφορά πρέπει να περιορίζεται σε ένα δεδομένο κριτήριο και αυτή είναι η δουλειά της ρήτρας HAVING.
Ας υποθέσουμε ότι θέλουμε να μάθουμε όλα τα έτη κυκλοφορίας για την ταινία με αναγνωριστικό κατηγορίας 8. Το παρακάτω σενάριο επιτυγχάνει αυτό το αποτέλεσμα.
SELECT * FROM `movies` GROUP BY `category_id`, `year_released` HAVING `category_id` = 8;
Εκτέλεση του παραπάνω σεναρίου στο MySQL Το Workbench σε σχέση με το myflixdb μας δίνει τα ακόλουθα αποτελέσματα που φαίνονται παρακάτω.
| movie_id | τίτλος | διευθυντής | έτος_κυκλοφόρησε | κατηγορία_αναγνωριστικό |
|---|---|---|---|---|
| 9 | Honey mooners | Τζον Σουλτς | 2005 | 8 |
| 5 | Μικρά κορίτσια του μπαμπά | Τιμή NULL | 2007 | 8 |
Μόνο οι ταινίες με αναγνωριστικό κατηγορίας 8 έχουν διατηρηθεί από τη συνθήκη HAVING.
Προειδοποίηση: MySQL Η έκδοση 5.7 και οι νεότερες εκδόσεις ενεργοποιούν τη λειτουργία ONLY_FULL_GROUP_BY από προεπιλογή και, σε αυτήν τη λειτουργία, η επιλογή SELECT * με όρο GROUP BY απορρίπτεται, επειδή τα movie_id, title και director δεν ομαδοποιούνται ούτε αθροίζονται. Στην παραγωγή, ονομάστε ρητά τις ομαδοποιημένες στήλες, για παράδειγμα. ΕΠΙΛΕΞΤΕ category_id, year_release ΑΠΟ ταινίες GROUP BY category_id, year_release ΕΧΟΝΤΑΣ category_id = 8;
ΠΟΥ vs ΕΧΟΝΤΑΣ vs ΟΜΑΔΟΠΟΙΗΣΗ ΚΑΤΑ vs ΤΑΞΙΝΟΜΗΣΗ ΚΑΤΑ
Οι αρχάριοι συχνά συνδυάζουν αυτές τις τέσσερις προτάσεις, επειδή όλες διαμορφώνουν το σύνολο αποτελεσμάτων. Η διαφορά έγκειται στο πότε MySQL τα εφαρμόζει: η συνάρτηση WHERE εκτελείται πριν από την ομαδοποίηση των γραμμών, η συνάρτηση HAVING εκτελείται μετά και η συνάρτηση ORDER BY εκτελείται τελευταία από όλες.
| Ρήτρα | Τι κάνει | Όταν εκτελείται | Δέχεται συναρτήσεις συγκέντρωσης |
|---|---|---|---|
| ΠΟΥ | Φιλτράρει μεμονωμένες γραμμές πριν από οποιαδήποτε ομάδαping. | Πριν από την ΟΜΑΔΟΠΟΙΗΣΗ ΜΕ | Οχι |
| GROUP BY | Συμπτύσσει τις γραμμές που μοιράζονται τις ίδιες τιμές σε μία γραμμή ανά ομάδα. | Μετά το WHERE | δεν ισχύει |
| HAVING | Φιλτράρει τις ομάδες που παράγονται από την GROUP BY. | Μετά την ΟΜΑΔΟΠΟΙΗΣΗ ΜΕ | Ναι, για παράδειγμα HAVING COUNT(*) > 2 |
| ΤΑΞΙΝΟΜΗΣΗ ΚΑΤΑ | Ταξινομεί τις γραμμές που επιβιώνουν από τις προηγούμενες ρήτρες. | Επίθετο | Ναι, μπορεί να ταξινομηθεί ένα συγκεντρωτικό ψευδώνυμο |
Η πρακτική συνέπεια είναι η απόδοση. Το φιλτράρισμα με WHERE αφαιρεί γραμμές πριν από την ομάδα.ping ξεκινά η εργασία, επομένως μια συνθήκη που δεν εξαρτάται από ένα συνολικό αποτέλεσμα ανήκει στο WHERE αντί για το HAVING.

