Ένθετα και συνδεδεμένα υποερωτήματα σε SQL, ΥΠΑΡΧΕΙ κατηγόρημα. Χρήση του τελεστή ΥΠΑΡΧΕΙ Ερωτήματα χρησιμοποιώντας τη συνάρτηση υπάρχει

ΟΠΟΥ ΥΠΑΡΧΕΙ

Το υποερώτημα ελέγχεται για μία ή περισσότερες σειρές. Εάν τουλάχιστον μία σειρά ικανοποιεί το ερώτημα, επιστρέφεται η δυαδική τιμή TRUE. Όταν καθορίζεται η προαιρετική λέξη-κλειδί ΟΧΙ, η δυαδική τιμή TRUE επιστρέφεται εάν το υποερώτημα δεν εμφανίσει αντίστοιχες σειρές.

υποερώτημα

Με βάση το πλήρως σχηματισμένο υποερώτημα, το σύνολο δεδομένων που προκύπτει ανακτάται.

Γενικοί κανόνες

Ο τελεστής EXISTS ελέγχει την ύπαρξη μίας ή περισσότερων σειρών σε ένα υποερώτημα του γονικού ερωτήματος.

ΕΠΙΛΟΓΗ * ΑΠΟ θέσεις εργασίας ΟΠΟΥ ΔΕΝ ΥΠΑΡΧΕΙ (ΕΠΙΛΟΓΗ * ΑΠΟ εργαζόμενο WHERE jobs.job_id=employye. job_id);

Αυτό το παράδειγμα επικυρώνεται σε ένα υποερώτημα εγγραφών χρησιμοποιώντας την προαιρετική λέξη-κλειδί ΟΧΙ. Το ακόλουθο παράδειγμα αναζητά συγκεκριμένες εγγραφές σε ένα υποερώτημα για να ανακτήσει το κύριο σύνολο αποτελεσμάτων.

ΕΠΙΛΟΓΗ au_lname ΑΠΟ συντάκτες ΟΠΟΥ ΥΠΑΡΧΕΙ (ΕΠΙΛΟΓΗ * ΑΠΟ εκδότες WHERE authors.city=publishers.city);

Αυτό το ερώτημα επιστρέφει τα επώνυμα των συγγραφέων (au_lname) που ζουν στην ίδια πόλη με τους εκδότες. Σημειώστε ότι μπορείτε να χρησιμοποιήσετε έναν αστερίσκο στο υποερώτημα επειδή το υποερώτημα θα πρέπει να επιστρέψει μόνο μία εγγραφή με δυαδική τιμή TRUE. Σε τέτοιες περιπτώσεις, οι στήλες δεν παίζουν ρόλο. Το βασικό σημείο είναι η ύπαρξη της χορδής.

Σε πολλά ερωτήματα, ο τελεστής ΥΠΑΡΧΕΙ εκτελεί την ίδια λειτουργία με ANY. Ο τελεστής EXISTS είναι συνήθως ο πιο αποτελεσματικός όταν χρησιμοποιείται με συσχετισμένα ερωτήματα.

Ο τελεστής EXISTS είναι σημασιολογικά ισοδύναμος με τον τελεστή ANY.

Ένα υποερώτημα σε μια πρόταση EXISTS εκτελεί συνήθως ένα από τα δύο είδη αναζητήσεων. Η πρώτη επιλογή είναι να χρησιμοποιήσετε έναν μπαλαντέρ αστερίσκου (π.χ. ΕΠΙΛΟΓΗ * ΑΠΟ…), οπότε δεν ανακτάτε κάποια συγκεκριμένη στήλη ή τιμή. Ο αστερίσκος εδώ σημαίνει "οποιαδήποτε στήλη". Η δεύτερη επιλογή είναι να επιλέξετε μόνο μία συγκεκριμένη στήλη στο υποερώτημα (για παράδειγμα, SELECT aujd FROM). Ορισμένες μεμονωμένες πλατφόρμες επιτρέπουν υποερωτήματα σε πολλές στήλες (π.χ. SELECT aujd, aujname FROM...). Ωστόσο, αυτή η δυνατότητα είναι σπάνια και θα πρέπει να αποφεύγεται σε κώδικα που πρέπει να μεταφερθεί σε άλλες πλατφόρμες.

Διαφορές μεταξύ πλατφορμών

Όλες οι πλατφόρμες υποστηρίζουν τον τελεστή EXISTS με τη μορφή που περιγράψαμε παραπάνω.

"Παλιά ήταν πιο εύκολο" - σκέφτηκα, κάθισα για να βελτιστοποιήσω το επόμενο ερώτημα στην SQL στούντιο διαχείρισης. Όταν έγραψα κάτω από τη MySQL, όλα ήταν πολύ πιο απλά - είτε λειτουργεί είτε όχι. Ή επιβραδύνετε ή όχι. Η εξήγηση έλυσε όλα μου τα προβλήματα, δεν χρειαζόταν τίποτα άλλο. Τώρα έχω ένα ισχυρό περιβάλλον ανάπτυξης, εντοπισμού σφαλμάτων και βελτιστοποίησης αιτημάτων και διαδικασιών / συναρτήσεων, και όλος αυτός ο σωρός δημιουργεί, κατά τη γνώμη μου, μόνο περισσότερα προβλήματα. Και όλα γιατί; Επειδή το ενσωματωμένο πρόγραμμα βελτιστοποίησης ερωτημάτων είναι κακό. Αν σε MySQL και PostgreSQL γράφω

Επιλέξτε * από τα a, b, c όπου a.id = b.id, b.id = c.id

και σε κάθε ένα από τα πιάτα θα υπάρχουν τουλάχιστον 5k γραμμές - όλα θα κρέμονται. Και δόξα τω Θεώ! Γιατί αλλιώς στον προγραμματιστή, στην καλύτερη, αναπτύσσεται η τεμπελιά για να γράφει σωστά και στη χειρότερη δεν καταλαβαίνει καθόλου τι κάνει! Εξάλλου, το ίδιο ερώτημα στο MSSQL θα περάσει με τον ίδιο τρόπο

Επιλέξτε * από μια ένωση b στο a.id = b.id ένωση c στο b.id = c.id

Το ενσωματωμένο optimizer θα χτενίσει το bydlozapros και όλα θα πάνε καλά.

Θα αποφασίσει επίσης μόνος του τι είναι καλύτερο να κάνει - να υπάρχει ή να ενταχθεί και πολλά άλλα. Και όλα θα λειτουργήσουν όσο το δυνατόν καλύτερα.

Υπάρχει μόνο ένα ΑΛΛΑ. Σε κάποιο σημείο, ο βελτιστοποιητής θα σκοντάψει σύνθετη ερώτησηκαι διπλώνει, και μετά έχεις τεράστιο πρόβλημα. Και θα το λάβετε, ίσως όχι αμέσως, αλλά όταν το βάρος των τραπεζιών φτάσει σε μια κρίσιμη μάζα.

Αυτή είναι λοιπόν η ουσία του άρθρου. υπάρχει και σε πολύ βαριές επιχειρήσεις. Στην πραγματικότητα, αυτό είναι ένα ξεχωριστό υποερώτημα για κάθεγραμμές αποτελεσμάτων. Και αν υπάρχει επίσης φωλιά, τότε αυτό είναι γενικά ένα φως σφαγίου. Όλα θα είναι εντάξει όταν επιστραφούν 1, 10, 50 σειρές. Δεν θα νιώσετε τη διαφορά, και ίσως η συμμετοχή θα είναι ακόμη πιο αργή. Όταν όμως τραβηχτεί το 500, αρχίζουν τα προβλήματα. 500 δευτερεύοντα αιτήματα σε ένα μόνο αίτημα είναι σοβαρά.

Let in and exists be better από την άποψη της ανθρώπινης κατανόησης, αλλά από την άποψη του κόστους χρόνου για ερωτήματα που επιστρέφουν 50+ σειρές, δεν είναι αποδεκτά.

Είναι απαραίτητο να κάνετε κράτηση ότι φυσικά, αν κάπου μειωθεί, κάπου πρέπει να φτάσει. Ναι, το join είναι πιο εντατικό σε πόρους όσον αφορά τη μνήμη, επειδή η ταυτόχρονη διατήρηση ολόκληρου του πίνακα τιμών και η λειτουργία του είναι πιο ακριβή από το να τραβήξετε δευτερεύοντα ερωτήματα για κάθε σειρά, απελευθερώνοντας γρήγορα τη μνήμη. Πρέπει να εξετάσετε συγκεκριμένα το αίτημα και να μετρήσετε εάν θα είναι κρίσιμο να χρησιμοποιήσετε επιπλέον μνήμη για χάρη του χρόνου ή όχι.

Θα δώσω παραδείγματα πλήρων αναλογιών. Γενικά, δεν έχω δει ακόμη αιτήματα τέτοιου βαθμού πολυπλοκότητας που να μην μπορούν να αναλυθούν σε έναν καταρράκτη ενώσεων. Ας πάρει μια μέρα, αλλά όλα μπορούν να αποκαλυφθούν.

Επιλέξτε * από το a όπου a.id στο (επιλέξτε το αναγνωριστικό από το β) επιλέξτε το * από το a όπου υπάρχει (επιλέξτε το επάνω 1 1 από το b όπου b.id = a.id) επιλέξτε το * από ένα σύνδεσμο b στο a.id = b. id επιλέξτε * από το a όπου το a.id δεν είναι (επιλέξτε το αναγνωριστικό από το β) επιλέξτε * από το a όπου δεν υπάρχει (επιλέξτε επάνω 1 1 από το b όπου b.id = a.id) επιλέξτε * από μια αριστερή ένωση b στο a. id = b.id όπου το b.id είναι μηδενικό

Επαναλαμβάνω - το MSSQL optimizer βελτιστοποιεί αυτά τα παραδείγματα για μέγιστη απόδοσηκαι σε τόσο απλά αιτήματα δεν θα υπάρξει ποτέ βλακεία.

Ας εξετάσουμε τώρα ένα παράδειγμα ενός πραγματικού ερωτήματος που έπρεπε να ξαναγραφτεί λόγω του γεγονότος ότι σε ορισμένες επιλογές απλώς κρεμόταν σφιχτά (η δομή είναι πολύ απλοποιημένη και οι έννοιες έχουν αντικατασταθεί, δεν υπάρχει λόγος να φοβάστε κάποια μη βέλτιστη δομή βάσης δεδομένων).

Πρέπει να τραβήξετε όλα τα διπλότυπα "προϊόντα" σε διαφορετικούς λογαριασμούς, εστιάζοντας στις παραμέτρους του προϊόντος, της ομάδας του και της γονικής ομάδας, εάν υπάρχουν.

Επιλέξτε d.product_id από το προϊόν S, product_group sg left join m_pg_dependency sd on (sg.product_group_id = sd.m_pg_dependency_child_id), προϊόν d, product_group dg join m_pg_dependency dd on .PRODUCT_GROUP_ID and d.PRODUCT_GROUP_ID=dg.PRODUCT_GROUP_ID and sg.PRODUCT_GROUP_PERSPEC=dg.PRODUCT_GROUP_PERSPEC and sg.PRODUCT_GROUP_NAME=dg.PRODUCT_GROUP_NAME and s.PRODUCT_NAME=d.PRODUCT_NAME and s.PRODUCT_TYPE=d.PRODUCT_TYPE and s.PRODUCT_IS_SECURE=d.PRODUCT_IS_SECURE and s.PRODUCT_MULTISELECT=d.PRODUCT_MULTISELECT and dg.PRODUCT_GROUP_IS_TMPL=0 and ((sd.M_PG_DEPENDENCY_CHILD_ID is null and dd.M_PG_DEPENDENCY_CHILD_ID is null) or exists (select 1 from PRODUCT_GROUP sg1, PRODUCT_GROUP dg1 where sd.M_PG_DEPENDENCY_PARENT_ID = sg1.PRODUCT_GROUP_ID and dd .M_PG_DEPENDENCY_PARENT_ID = dg1.PRODUCT_GROUP_ID και sg1.PRODUCT_GROUP_PERSPEC=dg1.PRODUCT_GROUP_PERSPEC και sg1.PRODUCT_GROUP_NAME=dg1.PRODUCT_GROUP ΑΜΕ και))

Και έτσι συμβαίνει όταν ο βελτιστοποιητής διπλώθηκε. Και για κάθε γραμμή εκτελούνταν το heavy exists που σκότωσε τη βάση.

Επιλέξτε d.PRODUCT_ID από το PRODUCT s join PRODUCT d στο s.PRODUCT_TYPE=d.PRODUCT_TYPE και s.PRODUCT_NAME=d.PRODUCT_NAME και s.PRODUCT_IS_SECURE=d.PRODUCT_IS_SECURE και s.PRODUCT_IS_SECURE και s.PRODUCT_IS_SECUREs. .PRODUCT_GROUP_ID join PRODUCT_GROUP dg on d.PRODUCT_GROUP_ID=dg.PRODUCT_GROUP_ID and sg.PRODUCT_GROUP_NAME=dg.PRODUCT_GROUP_NAME and sg.PRODUCT_GROUP_PERSPEC=dg.PRODUCT_GROUP_PERSPEC left join M_PG_DEPENDENCY sd on sg.PRODUCT_GROUP_ID = sd.M_PG_DEPENDENCY_CHILD_ID left join M_PG_DEPENDENCY dd on dg.PRODUCT_GROUP_ID = dd.M_PG_DEPENDENCY_CHILD_ID left join PRODUCT_GROUP sgp on sgp.PRODUCT_GROUP_ID = sd.M_PG_DEPENDENCY_PARENT_ID left join PRODUCT_GROUP dgp on dgp.PRODUCT_GROUP_ID = dd.M_PG_DEPENDENCY_PARENT_ID and sgp.PRODUCT_GROUP_NAME = dgp.PRODUCT_GROUP_NAME and isnull(sgp.PRODUCT_GROUP_IS_TMPL, 0) = isnull(dgp. PRODUCT_GROUP_IS_TMPL , 0) όπου (sd.M_PG_DEPENDENCY_CHILD_ID είναι μηδενικό και dd.M_PG_DEPENDENCY_CHILD_ID είναι μηδενικό) ή (sgp.PRODUCT_GROUP_NAME δεν είναι null και το dgp.PRODUCT_GROUP_NAME δεν είναι null) πηγαίνετε

Μετά από αυτούς τους μετασχηματισμούς, η απόδοση της προβολής αυξήθηκε εκθετικά στον αριθμό των προϊόντων που βρέθηκαν. Πιο συγκεκριμένα, ο χρόνος αναζήτησης παρέμενε πρακτικά ανεξάρτητος από τον αριθμό των αγώνων και ήταν πάντα πολύ μικρός. Οπως θα έπρεπε να είναι.

Αυτό είναι ένα σαφές παράδειγμα του τρόπου με τον οποίο η αξιόπιστη βελτιστοποίηση MSSQL μπορεί να παίξει ένα σκληρό αστείο. Μην τον εμπιστεύεστε, μην είστε τεμπέλης, ενώστε με λαβές, κάθε φορά σκεφτείτε ποιο είναι καλύτερο σε αυτή την κατάσταση - υπάρχει, μέσα ή εγγραφείτε.

Το κατηγόρημα SQL EXISTS εκτελεί μια λογική εργασία. ΣΕ Ερωτήματα SQLαυτό το κατηγόρημα χρησιμοποιείται σε εκφράσεις όπως

ΥΠΑΡΧΕΙ (ΕΠΙΛΟΓΗ * ΑΠΟ ΤΟ TABLE_NAME ...).

Αυτή η έκφραση επιστρέφει true όταν μια ή περισσότερες σειρές που ταιριάζουν με τη συνθήκη βρίσκονται από το ερώτημα και false όταν δεν βρίσκονται σειρές.

Για το ΔΕΝ ΥΠΑΡΧΕΙ, ισχύει το αντίθετο. Εκφραση

ΔΕΝ ΥΠΑΡΧΕΙ (ΕΠΙΛΟΓΗ * ΑΠΟ ΤΟ TABLE_NAME ...)

επιστρέφει true όταν δεν υπάρχουν σειρές για το ερώτημα και false όταν βρεθεί τουλάχιστον μία σειρά.

Τα πιο απλά ερωτήματα με το κατηγόρημα SQL ΥΠΑΡΧΕΙ

Στα παραδείγματα, εργαζόμαστε με τη βάση δεδομένων της βιβλιοθήκης και τους πίνακες της "Βιβλίο σε χρήση" (BOOKINUSE) και "Χρήστης" (ΧΡΗΣΤΗΣ). Προς το παρόν, χρειαζόμαστε μόνο τον πίνακα "Βιβλίο σε χρήση" (BOOKINUSE).

ΣυγγραφέαςΤίτλοςΈτος παμπΑριθμός ΑριθμΤαυτότητα χρήστη
ΤολστόιΠόλεμος και ειρήνη2005 28 65
ΤσέχοφΟ Βυσσινόκηπος2000 17 31
ΤσέχοφΕπιλεγμένες ιστορίες2011 19 120
ΤσέχοφΟ Βυσσινόκηπος1991 5 65
Ilf και PetrovΟι δώδεκα καρέκλες1985 3 31
Μαγιακόφσκιποιήματα1983 2 120
Είδος δαυκίουΓιατρός Ζιβάγκο2006 69 120
ΤολστόιΚυριακή2006 77 47
ΤολστόιΆννα Καρένινα1989 7 205
ΠούσκινΗ κόρη του καπετάνιου2004 25 47
ΓκόγκολΠαίζει2007 81 47
ΤσέχοφΕπιλεγμένες ιστορίες1987 4 205
Είδος δαυκίουΑγαπημένα2000 137 18

Παράδειγμα 1Προσδιορίστε τις ταυτότητες των χρηστών στους οποίους έχουν εκδοθεί βιβλία από τον Τολστόι, στους οποίους έχουν εκδοθεί βιβλία και από τον Τσέχοφ. Το εξωτερικό ερώτημα επιλέγει δεδομένα σχετικά με τους χρήστες στους οποίους έχουν εκδοθεί τα βιβλία του Τολστόι και το κατηγόρημα ΥΠΑΡΧΕΙ καθορίζει μια πρόσθετη συνθήκη που ελέγχεται στο εσωτερικό ερώτημα - χρήστες στους οποίους έχουν εκδοθεί τα βιβλία του Τσέχοφ. Μια πρόσθετη προϋπόθεση στο εσωτερικό ερώτημα είναι η αντιστοίχιση των αναγνωριστικών χρηστών από το εξωτερικό και το εσωτερικό ερώτημα: User_ID=tols_user.user_id. Το αίτημα θα έχει ως εξής:

Αυτό το ερώτημα θα επιστρέψει το ακόλουθο αποτέλεσμα:

Διαφορές μεταξύ κατηγορημάτων EXISTS και IN

Με την πρώτη ματιά σε ερωτήματα με το κατηγόρημα ΥΠΑΡΧΕΙ, μπορεί να έχετε την εντύπωση ότι είναι πανομοιότυπο κατηγόρημα ΙΝ. Αυτό είναι λάθος. Αν και μοιάζουν πολύ. Το κατηγόρημα IN αναζητά τιμές από το εύρος που καθορίζεται στο όρισμά του και εάν υπάρχουν τέτοιες τιμές, τότε επιλέγονται όλες οι σειρές που αντιστοιχούν σε αυτό το εύρος. Το αποτέλεσμα της δράσης του κατηγορήματος EXISTS είναι μια απάντηση ναι ή όχι στην ερώτηση εάν υπάρχουν καθόλου τιμές που αντιστοιχούν σε αυτές που καθορίζονται στο όρισμα. Επιπλέον, το κατηγόρημα IN προηγείται από το όνομα της στήλης με την οποία αναζητούνται σειρές που ταιριάζουν με τις τιμές στην περιοχή. Ας δούμε ένα παράδειγμα που δείχνει τη διαφορά μεταξύ του κατηγορήματος EXISTS και του κατηγόρημα IN, και το πρόβλημα που λύθηκε χρησιμοποιώντας το κατηγόρημα IN.

Παράδειγμα 4Λάβετε τα αναγνωριστικά των χρηστών που έχουν τα βιβλία που έχουν εκδοθεί στους συγγραφείς των οποίων τα βιβλία έχουν ελεγχθεί στον χρήστη με αναγνωριστικό 31. Το ερώτημα θα είναι το εξής:

Ταυτότητα χρήστη
120
65
205

Το εσωτερικό ερώτημα (μετά το IN) επιλέγει τους συγγραφείς: Τσέχοφ; Ilf και Petrov. Το εξωτερικό ερώτημα επιλέγει όλους τους χρήστες στους οποίους έχουν εκδοθεί βιβλία από αυτούς τους συγγραφείς. Βλέπουμε ότι, σε αντίθεση με το κατηγόρημα EXISTS, το κατηγόρημα IN προηγείται από το όνομα της στήλης, σε αυτήν την περίπτωση Author.

Ερωτήματα με το κατηγόρημα ΥΠΑΡΧΕΙ και πρόσθετες προϋποθέσεις

Εάν, εκτός από το κατηγόρημα EXISTS στο ερώτημα, εφαρμόζεται τουλάχιστον μία πρόσθετη συνθήκη, για παράδειγμα, προσδιορίζεται με τη χρήση αθροιστικές συναρτήσεις, τότε τέτοια ερωτήματα μπορούν να χρησιμεύσουν για απλή ανάλυση δεδομένων. Ας το δείξουμε αυτό με το ακόλουθο παράδειγμα.

Παράδειγμα 5Προσδιορίστε τα αναγνωριστικά των χρηστών στους οποίους έχει εκδοθεί τουλάχιστον ένα βιβλίο Παστερνάκ και στους οποίους έχουν εκδοθεί περισσότερα από 2 βιβλία. Γράφουμε το ακόλουθο ερώτημα, στο οποίο η πρώτη συνθήκη καθορίζεται από το κατηγόρημα EXISTS με ένα υποερώτημα και η δεύτερη συνθήκη με τον τελεστή HAVING πρέπει πάντα να ακολουθεί το υποερώτημα:

Αποτέλεσμα εκτέλεσης ερωτήματος:

Ταυτότητα χρήστη
120

Όπως φαίνεται από τον πίνακα BOOKINUSE, το βιβλίο του Pasternak εκδόθηκε και στον χρήστη με ID 18, αλλά του εκδόθηκε μόνο ένα βιβλίο και δεν περιλαμβάνεται στην επιλογή. Εάν εφαρμόσετε ξανά τη συνάρτηση COUNT σε ένα τέτοιο ερώτημα, αλλά για να μετρήσετε τις επιλεγμένες σειρές (ασκήστε το μόνοι σας), μπορείτε να λάβετε πληροφορίες σχετικά με το πόσοι χρήστες που διαβάζουν τα βιβλία του Pasternak διάβασαν επίσης βιβλία άλλων συγγραφέων. Αυτό είναι ήδη στον τομέα της ανάλυσης δεδομένων.

Ερωτήματα με το κατηγόρημα EXISTS σε δύο πίνακες

Τα ερωτήματα με το κατηγόρημα EXISTS μπορούν να ανακτήσουν δεδομένα από περισσότερους από έναν πίνακες. Πολλά προβλήματα μπορούν να λυθούν με το ίδιο αποτέλεσμα χρησιμοποιώντας Δήλωση JOIN, αλλά σε ορισμένες περιπτώσεις η χρήση του EXISTS σάς επιτρέπει να κάνετε ένα λιγότερο επαχθές ερώτημα. Είναι προτιμότερο να χρησιμοποιείται το EXISTS σε περιπτώσεις όπου ο πίνακας που προκύπτει θα περιέχει στήλες από έναν μόνο πίνακα.

Στο παρακάτω παράδειγμα, από την ίδια βάση δεδομένων, εκτός από τον πίνακα BOOKINUSE, χρειάζεστε και έναν πίνακα ΧΡΗΣΤΗ.

Το αποτέλεσμα του ερωτήματος θα είναι ο παρακάτω πίνακας:

Συγγραφέας
Τσέχοφ
Μαγιακόφσκι
Είδος δαυκίου

Όπως και με τη δήλωση JOIN, σε περιπτώσεις όπου υπάρχουν περισσότεροι από ένας πίνακες, θα πρέπει να χρησιμοποιούνται ψευδώνυμα πίνακα για να ελεγχθεί ότι ταιριάζουν οι τιμές των κλειδιών που συνδέουν τους πίνακες. Στο παράδειγμά μας, τα ψευδώνυμα πίνακα είναι bk and us και το κλειδί που συνδέει τους πίνακες είναι User_ID.

ΥΠΑΡΧΕΙ κατηγόρημα σε ενώσεις περισσότερων από δύο πινάκων

Τώρα θα δούμε με περισσότερες λεπτομέρειες γιατί είναι προτιμότερο να χρησιμοποιείται το EXISTS σε περιπτώσεις όπου στήλες από έναν μόνο πίνακα θα μπουν στον πίνακα που προκύπτει.

Συνεργαζόμαστε με τη βάση δεδομένων "Real Estate". Ο πίνακας συμφωνιών περιέχει δεδομένα σχετικά με τις συμφωνίες. Για τις εργασίες μας σε αυτόν τον πίνακα, η στήλη Τύπος θα είναι σημαντική με δεδομένα για το είδος της συναλλαγής - πώληση ή μίσθωση. Ο πίνακας Object περιέχει δεδομένα για αντικείμενα. Σε αυτόν τον πίνακα, χρειαζόμαστε τις τιμές των στηλών Rooms (αριθμός δωματίων) και LogBalc, που περιέχουν δεδομένα σχετικά με την παρουσία χαγιάτι ή μπαλκονιού σε μορφή boolean: 1 (ναι) ή 0 (όχι). Οι πίνακες Πελάτης, Διαχειριστής και Ιδιοκτήτης περιέχουν δεδομένα για πελάτες, διαχειριστές εταιρειών και ιδιοκτήτες ακινήτων, αντίστοιχα. Σε αυτούς τους πίνακες, FName και LName είναι το όνομα και το επίθετο, αντίστοιχα.

Παράδειγμα 7Προσδιορίστε πελάτες που έχουν αγοράσει ή νοικιάσει ακίνητα που δεν διαθέτουν χαγιάτι ή μπαλκόνι. Γράφουμε το ακόλουθο ερώτημα, στο οποίο το κατηγόρημα EXISTS καθορίζει μια πρόσβαση στο αποτέλεσμα της ένωσης δύο πινάκων:

Δεδομένου ότι οι στήλες επιλέγονται από τον πίνακα Client χρησιμοποιώντας τον τελεστή "αστερίσκος", θα εμφανιστούν όλες οι στήλες αυτού του πίνακα, στις οποίες θα υπάρχουν τόσες σειρές όσες και οι πελάτες που ταιριάζουν με τη συνθήκη που καθορίζεται από το κατηγόρημα EXISTS. Δεν χρειάζεται να εμφανίσουμε στήλες από τους πίνακες που ενώνονται με το υποερώτημα. Επομένως, για εξοικονόμηση χρόνου μηχανής, ανακτάται μόνο μία στήλη. Για να γίνει αυτό, μια μονάδα γράφεται μετά τη λέξη SELECT. Η ίδια τεχνική χρησιμοποιείται στα ερωτήματα στα ακόλουθα παραδείγματα.

Γράψτε μόνοι σας το ερώτημα SQL με το κατηγόρημα EXISTS και μετά δείτε τη λύση

Συνεχίζουμε να γράφουμε ερωτήματα SQL μαζί με το κατηγόρημα EXISTS

Παράδειγμα 9Προσδιορίστε τους ιδιοκτήτες των αντικειμένων που νοικιάστηκαν. Γράφουμε το ακόλουθο ερώτημα, στο οποίο το κατηγόρημα EXISTS καθορίζει επίσης μια πρόσβαση στο αποτέλεσμα της ένωσης δύο πινάκων:

Όπως και στο προηγούμενο παράδειγμα, όλα τα πεδία θα εμφανιστούν από τον πίνακα στον οποίο απευθύνεται το εξωτερικό ερώτημα.

Παράδειγμα 10Προσδιορίστε τον αριθμό των ιδιοκτητών, με τα αντικείμενα των οποίων ξόδεψε ο διαχειριστής Savelyev. Γράφουμε ένα ερώτημα στο οποίο το εξωτερικό ερώτημα έχει πρόσβαση στην ένωση τριών πινάκων και το κατηγόρημα EXISTS καθορίζει πρόσβαση μόνο σε έναν πίνακα:

Όλα τα ερωτήματα επικυρώνονται με βάση μια υπάρχουσα βάση δεδομένων. Επιτυχής χρήση!

Σχεσιακές βάσεις δεδομένων και Γλώσσα SQL

Novosibirsk State Academy of Economics and Management

ΕΡΓΑΣΤΗΡΙΟ ΕΡΓΑΣΤΗΡΙΟ ΓΙΑ ΤΗΝ ΠΕΙΘΑΡΧΙΑ

"ΒΑΣΗ ΔΕΔΟΜΕΝΩΝ"

Εργαστηριακές εργασίες N 7

"Γλώσσα βάσης δεδομένων SQL: εντολές χειρισμού δεδομένων»

NOVOSIBIRSK 2000

Η SQL είναι το σύντομο όνομα για τη γλώσσα δομημένης ερωτημάτων. Από το όνομα της γλώσσας είναι σαφές ότι ο κύριος σκοπός της είναι η δημιουργία αιτημάτων για πληροφορίες από τη βάση δεδομένων. Οι εντολές για την επιλογή δεδομένων αποτελούν τη βάση της γλώσσας χειρισμού δεδομένων DML - αναπόσπαστο μέρος της γλώσσας SQL. Ωστόσο, το DML αποτελείται από περισσότερα από εντολές για την ανάκτηση δεδομένων από μια βάση δεδομένων. Υπάρχουν επίσης εντολές για τροποποίηση δεδομένων, διαχείριση δεδομένων και άλλες.

Αυτό το εργαστήριο καλύπτει τα βασικά της γλώσσας DML. Σε εξέλιξη εργαστηριακές εργασίεςθα τηρούμε το πρότυπο SQL2.

Λόγω του γεγονότος ότι η SQL είναι μια ογκώδης γλώσσα, θα εξετάσουμε μόνο τις κύριες εντολές. Διάφορα συγκεκριμένα χαρακτηριστικά SQL καλύπτονται σε επόμενα εργαστήρια.

Για να εκτελέσετε εργαστηριακή εργασία, πρέπει να γνωρίζετε τα βασικά του μοντέλου σχεσιακών δεδομένων, τα βασικά της σχεσιακής άλγεβρας και του σχεσιακού λογισμού και τις αρχές της εργασίας με το MS SQL Server DBMS.

Ως αποτέλεσμα της εργαστηριακής εργασίας, θα μάθετε πώς να χειρίζεστε δεδομένα χρησιμοποιώντας εντολές SQL, λάβετε υπόψη τη διάλεκτο της γλώσσας που εφαρμόζεται στο MS SQL Server DBMS.

ΕΙΣΑΓΩΓΗ

Η SQL περιέχει ένα ευρύ φάσμα δυνατοτήτων χειρισμού δεδομένων, τόσο για τη δημιουργία ερωτημάτων όσο και για την ενημέρωση της βάσης δεδομένων. Αυτές οι δυνατότητες βασίζονται μόνο στη λογική δομή της βάσης δεδομένων και όχι στη φυσική δομή της, η οποία είναι συνεπής με τις απαιτήσεις του σχεσιακού μοντέλου.

Αρχικά, η δομή σύνταξης της SQL βασίστηκε (ή τουλάχιστον φαινόταν να βασίζεται) στον σχεσιακό λογισμό του Codd. Η Ένωση ήταν η μόνη υποστηριζόμενη πράξη σχεσιακής άλγεβρας.

Στην SQL2, εκτός από την παρόμοια σύνταξη σχεσιακού λογισμού που αναπτύχθηκε στο προηγούμενο πρότυπο, οι πράξεις ένωση, τομή, διαφορά και ένωση υλοποιούνται άμεσα. Οι λειτουργίες επιλογής, έργου και προϊόντος υποστηρίχθηκαν (και συνεχίζουν να υποστηρίζονται) σχεδόν άμεσα, ενώ οι λειτουργίες διαίρεσης και ανάθεσης υποστηρίζονται σε πιο δύσκαμπτη μορφή.

Αρχικά θα περιγράψουμε τη γλώσσα ερωτημάτων SQL και στη συνέχεια τις λειτουργίες εισαγωγής και τροποποίησης δεδομένων της. Οι λειτουργίες αλλαγής δεδομένων θα περιγραφούν τελευταία, καθώς η δομή τους βασίζεται σε κάποιο βαθμό στη δομή της γλώσσας ερωτήματος.

Απλές Ερωτήσεις

Για εμάς απλό αίτημαθα υπάρχει ένα ερώτημα που έχει πρόσβαση μόνο σε έναν πίνακα βάσης δεδομένων. Τα απλά ερωτήματα θα μας βοηθήσουν να απεικονίσουμε τη βασική δομή της SQL.

Απλό αίτημα.Ένα ερώτημα που έχει πρόσβαση μόνο σε έναν πίνακα βάσης δεδομένων.

Αίτηση:Ποιος εργάζεται ως σοβατζής;

WHERE SKILL_TYPE = "Γύψος"

Αποτέλεσμα:

G. Rickover

Αυτό το ερώτημα απεικονίζει τα τρία πιο κοινά φράσεις SQL: SELECT, FROM και WHERE. Αν και τα βάζουμε σε διαφορετικές γραμμές στο παράδειγμά μας, μπορούν όλα να βρίσκονται στην ίδια γραμμή. Μπορούν επίσης να έχουν διαφορετική εσοχή και οι λέξεις μέσα στις φράσεις μπορούν να διαχωριστούν με έναν αυθαίρετο αριθμό διαστημάτων. Εξετάστε τα χαρακτηριστικά κάθε φράσης.

Επιλέγω. Ο όρος SELECT παραθέτει τις στήλες που πρέπει να συμπεριληφθούν στον πίνακα που προκύπτει. Αυτές είναι πάντα στήλες κάποιου σχεσιακού πίνακα. Στο παράδειγμά μας, ο πίνακας που προκύπτει αποτελείται από μία στήλη (NAME), αλλά γενικά μπορεί να περιέχει πολλές στήλες. μπορεί επίσης να περιέχει υπολογισμένες τιμές ή σταθερές. Θα δώσουμε παραδείγματα για καθεμία από αυτές τις επιλογές. Εάν ο πίνακας που προκύπτει περιέχει περισσότερες από μία στήλες, τότε όλες οι απαιτούμενες στήλες παρατίθενται μετά SELECT εντολέςμέσω κόμματος. Για παράδειγμα, η φράση SELECT WORKER_ID, NAME θα οδηγήσει σε έναν πίνακα που αποτελείται από τις στήλες WORKER_ID και NAME.

ΕΠΙΛΟΓΗ φράσης.Καθορίζει τις στήλες του πίνακα που προκύπτει.

Από. Ο όρος FROM καθορίζει έναν ή περισσότερους πίνακες στους οποίους έχει πρόσβαση το ερώτημα. Όλες οι στήλες που παρατίθενται στους όρους SELECT και WHERE πρέπει να υπάρχουν σε έναν από τους πίνακες που παρατίθενται στον όρο FROM. Στην SQL2, αυτοί οι πίνακες μπορούν να οριστούν απευθείας στο σχήμα ως πίνακες βάσης ή προβολές δεδομένων ή μπορούν οι ίδιοι να είναι πίνακες χωρίς όνομα που προκύπτουν από ερωτήματα SQL. Στην τελευταία περίπτωση, το ερώτημα δίνεται ρητά στην εντολή FROM.

Φράση ΑΠΟ.Καθορίζει τους υπάρχοντες πίνακες στους οποίους αναφέρεται το ερώτημα.

Οπου. Η ρήτρα WHERE περιέχει μια συνθήκη. βάσει των οποίων επιλέγονται οι σειρές του πίνακα (πίνακες). Στο παράδειγμά μας, η προϋπόθεση είναι ότι η στήλη SKILL_TYPE πρέπει να περιέχει τη σταθερά "Plasterer" που περικλείεται σε απόστροφα, όπως γίνεται πάντα με τις σταθερές κειμένου στην SQL. Η ρήτρα WHERE είναι η πιο ασταθής εντολή SQL. μπορεί να περιέχει πολλές διαφορετικές συνθήκες. Μεγάλο μέρος της παρουσίασής μας θα αφιερωθεί στην απεικόνιση των διαφόρων δομών που επιτρέπονται στην ρήτρα WHERE.

ρήτρα WHERE.Καθορίζει τη συνθήκη βάσει της οποίας επιλέγονται οι σειρές από τους καθορισμένους πίνακες.

Το παραπάνω ερώτημα SQL επεξεργάζεται το σύστημα με την ακόλουθη σειρά: FROM, WHERE, SELECT. Δηλαδή, οι σειρές του πίνακα που καθορίζονται στην εντολή FROM τοποθετούνται στην περιοχή εργασίας για επεξεργασία. Στη συνέχεια, η ρήτρα WHERE εφαρμόζεται σε κάθε σειρά με τη σειρά. Όλες οι σειρές που δεν πληρούν την ρήτρα WHERE εξαιρούνται από την εξέταση. Στη συνέχεια, αυτές οι σειρές που ικανοποιούν τον όρο WHERE επεξεργάζονται από την εντολή SELECT. Στο παράδειγμά μας, το NAME επιλέγεται από κάθε τέτοια σειρά και όλες οι επιλεγμένες τιμές εμφανίζονται ως αποτελέσματα ερωτήματος.

Αίτηση:Παρέχετε όλα τα δεδομένα για κτίρια γραφείων.

WHERE TYPE = "Γραφείο"

Αποτέλεσμα:

BLDG IDADDRESSTYPEQLTY LEVELSTATUS

312 Vyazov St., 123 Office 2 2

210 Berezovaya st. 1011 Office Z 1

111 Osinovaya st. 1213 Office 4 1

Ένας αστερίσκος (*) σε μια εντολή SELECT σημαίνει "όλη τη γραμμή". Αυτή είναι μια εύχρηστη συντομογραφία που θα χρησιμοποιούμε συχνά.

Αίτηση:Ποιος είναι ο εβδομαδιαίος μισθός του κάθε ηλεκτρολόγου;

ΕΠΙΛΕΞΤΕ ΟΝΟΜΑ, "Εβδομαδιαίος μισθός = ", 40 * HRLY_RATE

WHERE SKILL_TYPE = "Ηλεκτρολόγος"

Αποτέλεσμα:

Μ. Faraday Εβδομαδιαίος μισθός = 500,00

H. Columbus Εβδομαδιαίος μισθός = 620,00

Αυτό το ερώτημα απεικονίζει τη χρήση και των δύο σταθερών χαρακτήρων (στο παράδειγμά μας "Εβδομαδιαίο μισθό = ") και υπολογισμούς στην εντολή SELECT. Στην εντολή SELECT, μπορείτε να εκτελέσετε υπολογισμούς που χρησιμοποιούν αριθμητικές στήλες και αριθμητικές σταθερές, καθώς και τυπικούς αριθμητικούς τελεστές ( +, -, *, /), ομαδοποιημένα όπως απαιτείται με παρενθέσεις. Έχουμε επίσης συμπεριλάβει ένα νέο Εντολή ORDER BY, το οποίο ταξινομεί το αποτέλεσμα του ερωτήματος με αύξουσα αλφαριθμητική σειρά κατά την καθορισμένη στήλη. Εάν θέλετε να ταξινομήσετε τα αποτελέσματα με φθίνουσα σειρά, τότε πρέπει να προσθέσετε DESC στην εντολή. Ο όρος ORDER BY μπορεί να ταξινομήσει τα αποτελέσματα κατά πολλαπλές στήλες, μερικές σε αύξουσα σειρά, άλλες σε φθίνουσα σειρά. Η στήλη ταξινόμησης πρωτεύοντος κλειδιού καθορίζεται πρώτα.

σταθερά χαρακτήρα.Μια σταθερά που αποτελείται από γράμματα, αριθμούς και «ειδικούς» χαρακτήρες.

Αίτηση:Ποιος έχει ωριαία χρέωση από $10 έως $12;

WHERE HRLY_RATE >= 10 ΚΑΙ HRLY_RATE< - 12

Αποτέλεσμα:

ΤΑΥΤΟΤΗΤΑ ΕΡΓΑΤΟΥΟΝΟΜΑ HRLY_RATE SKILL_TYPE SUPV_ID

Αυτό το ερώτημα επεξηγεί μερικά από τα προηγμένα χαρακτηριστικά της εντολής WHERE: τελεστές σύγκρισης και τη λειτουργία Boolean AND. Οι έξι τελεστές σύγκρισης (=,<>(όχι ίσο),<, >, <=, >=). Οι τελεστές Boole AND (AND), OR (OR) και NOT (HE) μπορούν να χρησιμοποιηθούν για τη δημιουργία σύνθετων συνθηκών ή για την άρνηση μιας συνθήκης. Οι παρενθέσεις μπορούν να χρησιμοποιηθούν για την ομαδοποίηση συνθηκών, όπως συνηθίζεται στις γλώσσες προγραμματισμού.

Συγκριτικοί τελεστές =,<>, <, >, <=, >=.

Λειτουργίες BooleanΚΑΙ (ΚΑΙ), Ή (Ή) και ΟΧΙ (ΑΥΤΟΣ) .

Θα μπορούσατε επίσης να χρησιμοποιήσετε τον τελεστή BETWEEN (between) για να διατυπώσετε αυτό το ερώτημα:

ΠΟΥ HRLY_RATE Μεταξύ 10 ΚΑΙ 12

Το BETWEEN μπορεί να χρησιμοποιηθεί για να συγκρίνει κάποια τιμή με δύο άλλες τιμές, η πρώτη από τις οποίες είναι μικρότερη από τη δεύτερη, εάν η συγκριτική τιμή μπορεί να είναι ίση με καθεμία από τις δεδομένες τιμές ή οποιαδήποτε τιμή ενδιάμεσα.

Ερώτημα: Καταγράψτε σοβατζήδες, στεγαστές και ηλεκτρολόγους.

WHERE SKILL_TYPE IN ("Γύψος", "Στέγη", "Ηλεκτρολόγος")

Αποτέλεσμα:

WORKER_ID ΟΝΟΜΑ HRLY_RATE SKILL_TYPE SUPV_ID

1412 C. Nemo 13,75 Γύψος 1520

2920 R. Garrett 10.00 Roofer 2920

1520 G. Rickover 11.75 Γύψος 1520

Αυτό το ερώτημα εξηγεί τη χρήση του τελεστή σύγκρισης IN (B). Η ρήτρα WHERE είναι αληθής εάν ο τύπος επαγγέλματος της σειράς είναι εντός του συνόλου στις παρενθέσεις, δηλαδή εάν ο τύπος επαγγέλματος είναι σοβατιστής, στεγαστής ή ηλεκτρολόγος. Θα δούμε ξανά τον τελεστή IN στα δευτερεύοντα ερωτήματα.

Ας υποθέσουμε ότι δεν μπορούμε να θυμηθούμε ακριβώς την ορθογραφία της ειδικότητας: «ηλεκτρολόγος» ή «ηλεκτρολόγος μηχανικός» ή κάτι άλλο. Οι χαρακτήρες μπαλαντέρ που αντικαθιστούν ακαθόριστες συμβολοσειρές χαρακτήρων διευκολύνουν την εύρεση ανακριβών ορθογραφικών γραμμάτων σε ένα ερώτημα.

Σύμβολα προτύπων.Χαρακτήρες που αντικαθιστούν ακαθόριστες συμβολοσειρές χαρακτήρων.

Αίτηση:Καταγράψτε τους εργαζομένους των οποίων ο τύπος εργασίας αρχίζει με Elek.

WHERE SKILL_TYPE LIKE ("Elek%")

Αποτέλεσμα:

Αναγνωριστικό ΕΡΓΑΤΗ ΟΝΟΜΑ HRLY_RATE SKILL_TYPE SUPV_ID

1235 M.Faraday 12.50 Ηλεκτρολόγος 1311

1311 H. Columbus 15.50 Ηλεκτρολόγος 1311

Υπάρχουν δύο χαρακτήρες μπαλαντέρ στην SQL: % (ποσοστό) και _ (υπογράμμιση). Η υπογράμμιση αντικαθιστά ακριβώς έναν απροσδιόριστο χαρακτήρα. Το ποσοστό αντικαθιστά έναν αυθαίρετο αριθμό χαρακτήρων, ξεκινώντας από το μηδέν. Όταν χρησιμοποιούνται χαρακτήρες μπαλαντέρ, ο τελεστής LIKE (όπως) απαιτείται για τη σύγκριση μεταβλητών χαρακτήρων με σταθερές. Άλλα παραδείγματα:

ΟΝΟΜΑ ΑΡΕΣΕΙ "__Columbus"

ΟΝΟΜΑ ΑΡΕΣΕΙ "__K%"

Η συνθήκη στο πρώτο παράδειγμα είναι αληθής εάν το NAME αποτελείται από δύο χαρακτήρες ακολουθούμενους από το "Columbus". Στον πίνακα WORKER, όλα τα ονόματα ξεκινούν με ένα πρώτο αρχικό και μια τελεία. Έτσι, με αυτήν την προϋπόθεση, εμείς βρείτε όλους τους εργαζόμενους με το επώνυμο "Κολόμβος". Η συνθήκη του δεύτερου παραδείγματος σάς επιτρέπει να βρείτε όλους τους υπαλλήλους των οποίων τα επώνυμα αρχίζουν με το γράμμα "K".

Αίτηση:Βρείτε όλες τις δουλειές που ξεκινούν μέσα στις επόμενες δύο εβδομάδες.

ΠΟΥ ΕΝΑΡΞΗ _ΗΜΕΡΟΜΗΝΙΑ ΜΕΤΑΞΥ ΤΡΕΧΟΥΣΑ_ΗΜΕΡΟΜΗΝΙΑ ΚΑΙ

Αποτέλεσμα:(Υποθέστε ότι η τρέχουσα ημερομηνία είναι CURRENT DATE = 10.10)

WORKER_ID BLDG_ID START_DATE NUM_DAYS

1235 312 10.10 5

1235 515 17.10 22

3231 111 10.10 8

1412 435 15.10 15

3231 312 24.10 20

1311 460 23.10 24

Αυτό το ερώτημα απεικονίζει τη χρήση του τελεστή BETWEEN (μεταξύ) με τιμές τύπου ημερομηνίας (ημερομηνία) και διαστήματος (διάστημα). Η CURRENT_DATE είναι μια συνάρτηση που επιστρέφει πάντα τη σημερινή ημερομηνία. Εκφραση

CURRENT_DATE + INTERVAL "14" ΗΜΕΡΑ

προσθέτει ένα διάστημα δύο εβδομάδων στην τρέχουσα ημερομηνία. Έτσι, επιλέγεται ASIGNMENT (υποθέτοντας ότι σήμερα είναι 10/10) εάν η τιμή της στήλης START_DATE είναι μεταξύ 10/10 και 10/24. Αυτό δείχνει ότι μπορούμε να προσθέσουμε τιμές διαστήματος στα πεδία ημερομηνίας. Επιπλέον, μπορούμε να πολλαπλασιάσουμε τις τιμές κενού με ακέραιες τιμές. Για παράδειγμα, ας υποθέσουμε ότι θέλουμε να μάθουμε ποιος θα είναι ο αριθμός των εβδομάδων σε έναν συγκεκριμένο αριθμό εβδομάδων (που συμβολίζεται με τη μεταβλητή NUM_WEEKS (NUMBER OF WEEKS)). Μπορούμε να το κάνουμε ως εξής:

CURRENT_DATE + INTERVAL "7" ΗΜΕΡΑ * NUM_WEEKS

2. Ερωτήματα πολλών πινάκων

Η δυνατότητα σύνδεσης στοιχείων δεδομένων πέρα ​​από τα όρια του ίδιου πίνακα είναι σημαντική σε οποιαδήποτε γλώσσα βάσης δεδομένων. Στη σχεσιακή άλγεβρα, αυτή η συνάρτηση εκτελείται από την πράξη ένωσης. Αν και μεγάλο μέρος της SQL βασίζεται απευθείας στον σχεσιακό λογισμό, η SQL συνδέει δεδομένα από διαφορετικούς πίνακες με παρόμοιο τρόπο με τον τρόπο που κάνει μια πράξη ένωσης σχεσιακής άλγεβρας. Θα δείξουμε τώρα πώς γίνεται αυτό. Σκεφτείτε το ερώτημα:

Αίτηση:

Τα στοιχεία που απαιτούνται για την απάντηση βρίσκονται σε δύο πίνακες: ΕΡΓΑΤΗΣ και ΕΡΓΑΣΙΑ. Η λύση SQL απαιτεί την παράθεση και των δύο πινάκων στον όρο FROM και τον καθορισμό ενός ειδικού τύπου ρήτρας WHERE:

ΕΠΙΛΕΞΤΕ SKILL_TYPE

ΑΠΟ ΕΡΓΑΖΟΜΕΝΗ, ΕΡΓΑΣΙΑ

WHERE WORKER.WORKER_ID = ASIGNMENT.WORKER_ID

ΚΑΙ BLDG_ID = 435

Τι συμβαίνει εδώ? Πρέπει να εξετάσουμε δύο στάδια στην επεξεργασία ενός δεδομένου αιτήματος από το σύστημα.

1. Ως συνήθως, η ρήτρα FROM επεξεργάζεται πρώτα. Ωστόσο, σε αυτήν την περίπτωση, δεδομένου ότι δύο πίνακες καθορίζονται στην εντολή, το σύστημα δημιουργεί ένα καρτεσιανό γινόμενο των σειρών αυτών των πινάκων. Αυτό σημαίνει ότι δημιουργείται ένας (λογικά) ένας μεγάλος πίνακας, που αποτελείται από τις στήλες και των δύο πινάκων, στους οποίους κάθε γραμμή ενός πίνακα ζευγαρώνεται με κάθε γραμμή του άλλου πίνακα. Στο παράδειγμά μας, δεδομένου ότι ο πίνακας WORKER έχει πέντε στήλες και ο πίνακας ASSIGNMENT έχει τέσσερις στήλες, το καρτεσιανό γινόμενο που δημιουργείται από την εντολή FROM θα έχει εννέα στήλες. Ο συνολικός αριθμός σειρών του καρτεσιανού γινόμενου είναι m * n, όπου m είναι ο αριθμός των σειρών στον πίνακα WORKER. και n είναι ο αριθμός των σειρών στον πίνακα ASIGNMENT. Δεδομένου ότι υπάρχουν 7 σειρές στον πίνακα WORKER και 19 σειρές στον πίνακα ASIGNMENT, το καρτεσιανό προϊόν θα περιέχει 7x19 ή 133 σειρές. Εάν στην εντολή FROM παρατίθενται περισσότεροι από δύο πίνακες, τότε δημιουργείται το καρτεσιανό γινόμενο όλων των πινάκων που καθορίζονται στην εντολή.

καρτεσιανό προϊόν. Το αποτέλεσμα της ένωσης κάθε σειράς ενός πίνακα με καθεσειρά σε άλλο πίνακα.

2. Μετά τη δημιουργία του γιγαντιαίου σχεσιακού πίνακα, το σύστημα εξακολουθεί να εφαρμόζει τον όρο WHERE όπως πριν. Κάθε γραμμή του πίνακα που δημιουργείται από την εντολή FROM. ελέγχεται έναντι της συνθήκης WHERE. Οι σειρές που δεν πληρούν την προϋπόθεση εξαιρούνται από την εξέταση. Στη συνέχεια, η ρήτρα SELECT εφαρμόζεται στις υπόλοιπες σειρές.

Η ρήτρα WHERE στο ερώτημά μας περιέχει δύο προϋποθέσεις:

1. ΕΡΓΑΤΗΣ. WORKER_ID = ASIGNMENT.WORKER_ID

2.BLDG_ID = 435

Η πρώτη από αυτές τις προϋποθέσεις είναι η συνθήκη ένωσης. Σημειώστε ότι επειδή και οι δύο πίνακες WORKER και ASIGNMENT περιέχουν μια στήλη με το όνομα WORKER_ID, το καρτεσιανό γινόμενο τους θα περιέχει δύο στήλες με αυτό το όνομα. Για να τα ξεχωρίσουμε, προηγούμε το όνομα της στήλης με το όνομα του πίνακα προέλευσης, χωρίζοντάς τον με μια τελεία.

Η πρώτη συνθήκη σημαίνει ότι σε οποιαδήποτε επιλεγμένη σειρά, η τιμή της στήλης WORKER_ID από τον πίνακα WORKER πρέπει να ταιριάζει με την τιμή της στήλης WORKER_ID από τον πίνακα ASSIGNMENT. Στην πραγματικότητα ενώνουμε δύο πίνακες κατά WORKER_ID. Όλες οι σειρές στις οποίες οι τιμές αυτών των δύο στηλών δεν είναι ίσες εξαιρούνται από τον πίνακα προϊόντων. Ακριβώς το ίδιο συμβαίνει κατά την εκτέλεση της λειτουργίας φυσικής ένωσης μιας σχεσιακής άλγεβρας. (Ωστόσο, υπάρχει ακόμα κάποια διαφορά από μια φυσική σύνδεση: η SQL δεν καταργεί αυτόματα την επιπλέον στήλη WORKER_ID). Η πλήρης ένωση αυτών των δύο πινάκων με την πρόσθετη συνθήκη BLDG_ID = 435 φαίνεται στο σχ. 1. Η εφαρμογή της εντολής SELECT θα δώσει τελικά το ακόλουθο αποτέλεσμα ερωτήματος:

ΕΙΔΟΣ ΔΕΞΙΟΤΗΤΑΣ

Σοβατζής

Στεγαστής

Ηλεκτρολόγος

Ρύζι. 1. Ένταξη των πινάκων ΕΡΓΑΤΗΣ και ΕΡΓΑΣΙΑΣ

Τώρα θα σας δείξουμε πώς να συνδέσετε έναν πίνακα στον εαυτό του στην SQL.

Αίτηση:Καταγράψτε τους υπαλλήλους με τα ονόματα των διευθυντών τους.

ΕΠΙΛΕΞΤΕ A.WORKER_NAME, B.WORKER_NAME

ΑΠΟ ΤΟΝ ΕΡΓΑΤΗ Α, ΤΗΝ ΕΡΓΑΤΗ Β

WHERE B.WORKER_ID = A.SUPV_ID

Η ρήτρα FROM σε αυτό το παράδειγμα δημιουργεί δύο "αντίγραφα" του πίνακα WORKER, δίνοντάς τους τα ψευδώνυμα A και B. Το ψευδώνυμο είναι ένα εναλλακτικό όνομα που δίνεται στον πίνακα. Στη συνέχεια, τα αντίγραφα A και B του πίνακα WORKER συνδέονται με την εντολή WHERE με βάση την προϋπόθεση ότι το WORKER_ID στο B και το SUPV_ID στο A είναι ίσα. Έτσι, κάθε σειρά από το A ενώνεται με τη σειρά B που περιέχει πληροφορίες για τον διαχειριστή σειράς A (Εικ. 2).

Ρύζι. 2. Συνένωση δύο αντιγράφων του πίνακα WORKER

Επιλέγοντας δύο ονόματα εργαζομένων από κάθε γραμμή, λαμβάνουμε την απαιτούμενη λίστα:

A.NAMEB.NAME

M.Faraday H.Columbus

C.Nemo G.Rickover R.Garrett R.Garrett

P. Mason P. Mason G. Rickover G. Rickover H. Columbus H. Columbus J. Barrister P. Mason

Ψευδώνυμο.Εναλλακτικό όνομα που δίνεται στον πίνακα.

Ο A.WORKER_NAME αντιπροσωπεύει έναν εργαζόμενο και ο B.WORKER_NAME αντιπροσωπεύει έναν διαχειριστή. Λάβετε υπόψη ότι ορισμένοι εργαζόμενοι είναι οι δικοί τους διευθυντές, κάτι που προκύπτει από την ισότητα WORKER_ID - SUPV_ID που εκτελείται στις γραμμές τους.

Στην SQL, μπορείτε να συνδέσετε περισσότερους από δύο πίνακες τη φορά:

Αίτηση

ΕΠΙΛΟΓΗ WORKER_NAME

ΑΠΟ ΕΡΓΑΤΗ, ΕΡΓΑΣΙΑ, ΚΤΙΡΙΟ

WHERE WORKER.WORKER_ID = ASIGNMENT.WORKER_ID AND ASIGNMENT.BLDG_ID = BUILDING.BLDG_ID ΚΑΙ

TYPE = "Γραφείο"

Αποτέλεσμα:

M. Faraday

G. Rickover

J. Barrister

Σημειώστε ότι εάν ένα όνομα στήλης (για παράδειγμα, WORKER_ID ή BLDG_ID) εμφανίζεται σε περισσότερους από έναν πίνακες, τότε για να αποφευχθεί η ασάφεια, πρέπει να προηγηθεί το όνομα της στήλης με το όνομα του πίνακα προέλευσης. Αλλά αν το όνομα της στήλης εμφανίζεται μόνο σε έναν πίνακα, όπως το TYPE στο παράδειγμά μας, τότε δεν υπάρχει ασάφεια, επομένως το όνομα του πίνακα δεν χρειάζεται να καθοριστεί.

Οι εντολές SQL σε αυτό το ερώτημα δημιουργούν έναν πίνακα από τρεις πίνακες σχεσιακών βάσεων δεδομένων. Οι δύο πρώτοι πίνακες ενώνονται με WORKER_ID και μετά ο τρίτος πίνακας ενώνεται με BLDG_ID στον πίνακα που προκύπτει. Κατάσταση

TYPE = "Γραφείο"

η εντολή WHERE έχει ως αποτέλεσμα την εξαίρεση όλων των σειρών εκτός από τις σειρές που σχετίζονται με κτίρια γραφείων. Αυτό ταιριάζει με τις απαιτήσεις του αιτήματος.

3. Υποερωτήματα

Υποερώτημα.Αίτημα εντός αιτήματος

Ένα υποερώτημα μπορεί να τοποθετηθεί στον όρο WHERE ενός ερωτήματος, επεκτείνοντας έτσι τις δυνατότητες του όρου WHERE. Εξετάστε ένα παράδειγμα.

Αίτηση:Ποιες είναι οι ειδικότητες των εργαζομένων που τοποθετούνται στο κτίριο 435;

ΕΠΙΛΟΓΗ SKTLL_TYPE

FROM WORKER WHERE WORKER_ID IN

(ΕΠΙΛΟΓΗ WORKER_ID

WHERE BLDG_ID = 435)

Υποερώτημα σε αυτό το παράδειγμα

(ΕΠΙΛΟΓΗ WORKER_ID

WHERE BLDG_ID = 435)

Ένα ερώτημα που περιέχει ένα δευτερεύον ερώτημα καλείται εξωτερικό αίτημαή κύριο αίτημα. Το δευτερεύον ερώτημα έχει ως αποτέλεσμα το ακόλουθο σύνολο αναγνωριστικών εργαζομένων:

ΤΑΥΤΟΤΗΤΑ ΕΡΓΑΤΟΥ

εξωτερικό αίτημα.Το κύριο ερώτημα, το οποίο περιέχει όλα τα δευτερεύοντα ερωτήματα.

Αυτό το σύνολο αναγνωριστικών παίρνει στη συνέχεια τη θέση ενός δευτερεύοντος ερωτήματος στο εξωτερικό ερώτημα. Από αυτό το σημείο και μετά, το εξωτερικό ερώτημα εκτελείται χρησιμοποιώντας το σύνολο που δημιουργήθηκε από το υποερώτημα. Το εξωτερικό ερώτημα επεξεργάζεται κάθε γραμμή του πίνακα WORKER σύμφωνα με τον όρο WHERE. Εάν το WORKER_ID της σειράς βρίσκεται στο σύνολο (IN) που δημιουργήθηκε από το υποερώτημα, τότε επιλέγεται το SKILL_TYPE της σειράς και εμφανίζεται στον πίνακα που προκύπτει:

ΕΙΔΟΣ ΔΕΞΙΟΤΗΤΑΣ

Σοβατζής

Στεγαστής

Ηλεκτρολόγος

Είναι πολύ σημαντικό ο όρος SELECT του υποερωτήματος να περιέχει το WORKER_ID και μόνο το WORKER_ID. Διαφορετικά, η ρήτρα WHERE του εξωτερικού ερωτήματος, που σημαίνει ότι το WORKER_ID βρίσκεται στο σύνολο των αναγνωριστικών εργαζομένων, δεν θα είχε νόημα.

Σημειώστε ότι το υποερώτημα μπορεί λογικά να εκτελεστεί πριν ακόμη και μία σειρά θεωρηθεί από το κύριο ερώτημα. Κατά μία έννοια, το υποερώτημα είναι ανεξάρτητο από το κύριο ερώτημα. Μπορεί να εκτελεστεί ως πλήρες ερώτημα. Λέμε ότι ένα τέτοιο υποερώτημα δεν συσχετίζεται με το κύριο ερώτημα. Όπως θα δούμε σύντομα, τα υποερωτήματα μπορούν να συσχετιστούν.

Μη συσχετισμένο υποερώτημα.Ένα δευτερεύον ερώτημα του οποίου η τιμή δεν εξαρτάται από κανένα εξωτερικό ερώτημα.

Ακολουθεί ένα παράδειγμα υποερωτήματος μέσα σε ένα υποερώτημα.

Αίτηση: Κατάλογος εργαζομένων που έχουν τοποθετηθεί σε κτίρια γραφείων.

Και πάλι εξετάζουμε το ερώτημα με το οποίο μάθαμε τη σύνδεση.

ΕΠΙΛΟΓΗ WORKER_MAME

WHERE WORKER_ID IN

(ΕΠΙΛΟΓΗ WORKER_ID

WHERE BLDG_ID IN

WHERE TYPE = "Γραφείο"))

Αποτέλεσμα:

M. Faraday

G. Rickover

J. Barrister

Σημειώστε ότι δεν χρειάζεται να προηγούνται τα ονόματα των στηλών πουθενά με τα ονόματα των πινάκων, καθώς κάθε υποερώτημα επεξεργάζεται έναν και μόνο έναν πίνακα, επομένως δεν μπορεί να υπάρχει ασάφεια.

Το ερώτημα εκτελείται με σειρά από μέσα προς τα έξω. Δηλαδή, πρώτα εκτελείται το πιο εσωτερικό ερώτημα (ή "κατώτατο"), μετά εκτελείται το υποερώτημα που το περιέχει και μετά το εξωτερικό ερώτημα.

Συσχετισμένα υποερωτήματα. Όλα τα υποερωτήματα που συζητήθηκαν παραπάνω ήταν ανεξάρτητα από τα κύρια ερωτήματα στα οποία χρησιμοποιήθηκαν. Με τον όρο ανεξαρτησία, εννοούμε ότι τα δευτερεύοντα ερωτήματα μπορούν να εκτελεστούν μόνα τους ως πλήρη ερωτήματα. Περνάμε τώρα σε μια κατηγορία υποερωτημάτων των οποίων τα αποτελέσματα μπορεί να εξαρτώνται από τη σειρά που εξετάζεται από το κύριο ερώτημα. Τέτοια υποερωτήματα ονομάζονται συσχετισμένα υποερωτήματα.

Συσχετισμένο υποερώτημα. Ένα υποερώτημα του οποίου το αποτέλεσμα εξαρτάται από τη σειρά που εξετάζεται από το κύριο ερώτημα.

Αίτηση:Καταγράψτε τους υπαλλήλους των οποίων οι ωριαίες χρεώσεις είναι υψηλότερες από αυτές των διευθυντών τους.

ΕΠΙΛΟΓΗ WORKER_NAME

WHERE A.HRLY_RATE >

(ΕΠΙΛΟΓΗ B.HRLY_RATE

WHERE B.WORKER_ID = A.SUPV_ID)

Αποτέλεσμα:

Τα λογικά βήματα για την εκτέλεση αυτού του ερωτήματος είναι:

1. Το σύστημα δημιουργεί δύο αντίγραφα του πίνακα WORKER: αντίγραφο A και αντίγραφο B. Σύμφωνα με τον τρόπο που τα ορίσαμε, το A αναφέρεται στον εργαζόμενο, το B στον διευθυντή.

2. Στη συνέχεια, το σύστημα εξετάζει κάθε γραμμή A. Αυτή η σειρά επιλέγεται εάν ικανοποιεί τον όρο WHERE. Αυτή η συνθήκη σημαίνει ότι μια σειρά θα επιλεγεί εάν η τιμή HRLY_RATE της είναι μεγαλύτερη από την τιμή HRLY_RATE που δημιουργείται από το υποερώτημα.

3. Το υποερώτημα επιλέγει την τιμή HRLY_RATE από τη σειρά Β, της οποίας το WORKER_ID είναι ίσο με το SUPV_ID της σειράς Α, σε αυτή τη στιγμήθεωρείται από το κύριο ερώτημα. Αυτό είναι το HRLY_RATE του διαχειριστή.

Σημειώστε ότι επειδή το A.HRLY_RATE μπορεί να συγκριθεί μόνο με μία τιμή, το υποερώτημα πρέπει να επιστρέψει μόνο μία τιμή. Αυτή η τιμή ποικίλλει ανάλογα με τη σειρά Α που εξετάζεται. Έτσι, το υποερώτημα συσχετίζεται με το κύριο ερώτημα. Θα δούμε περισσότερα παραδείγματα συσχετισμένων υποερωτημάτων αργότερα, όταν εξερευνήσουμε τις ενσωματωμένες συναρτήσεις.

ΥΠΑΡΧΕΙ και ΔΕΝ ΥΠΑΡΧΕΙ τελεστές

Ας υποθέσουμε ότι θέλουμε να εντοπίσουμε εργαζόμενους που δεν έχουν ανατεθεί να εργαστούν σε ένα κτίριο. Επιφανειακά, φαίνεται ότι ένα τέτοιο αίτημα μπορεί εύκολα να γίνει με απλή άρνηση της καταφατικής εκδοχής του αιτήματος. Ας υποθέσουμε, για παράδειγμα, ότι μας ενδιαφέρει ένα κτίριο με BLDG_ID 435. Εξετάστε το ερώτημα:

ΕΠΙΛΟΓΗ WORKER_ID

WHERE BLDG_ID ΟΧΙ 435

Δυστυχώς, αυτή είναι η λάθος διατύπωση της λύσης. Το ερώτημα θα μας δώσει απλώς τις ταυτότητες των εργαζομένων που εργάζονται σε άλλα κτίρια. Προφανώς, ορισμένα από αυτά μπορεί να ανατεθούν και στο κτίριο 435.

Η καλά διαμορφωμένη λύση χρησιμοποιεί τον τελεστή ΔΕΝ ΥΠΑΡΧΕΙ (δεν υπάρχει):

ΕΠΙΛΟΓΗ WORKER_ID

ΟΠΟΥ ΔΕΝ ΥΠΑΡΧΕΙ

WHERE ASIGNMENT.WORKER_ID = WORKER.WORKER_ID ΚΑΙ

Αποτέλεσμα:

WORKER_ID

Οι τελεστές EXISTS και NOT EXISTS τοποθετούνται πάντα πριν από το υποερώτημα. Το EXISTS αξιολογείται ως true εάν το σύνολο που δημιουργείται από το υποερώτημα δεν είναι κενό. Εάν το σύνολο που δημιουργείται από το υποερώτημα είναι κενό, τότε το EXISTS είναι ψευδές. Ο χειριστής ΔΕΝ ΥΠΑΡΧΕΙ, φυσικά, λειτουργεί ακριβώς το αντίθετο. Είναι αληθές εάν το αποτέλεσμα του υποερωτήματος είναι κενό και ψευδές διαφορετικά.

ΥΠΑΡΧΕΙ χειριστής. Επιστρέφει true εάν το σύνολο αποτελεσμάτων δεν είναι κενό.

ΔΕΝ ΥΠΑΡΧΕΙ χειριστής. Επιστρέφει true εάν το σύνολο αποτελεσμάτων είναι κενό.

Σε αυτό το παράδειγμα, χρησιμοποιήσαμε τον τελεστή ΔΕΝ ΥΠΑΡΧΕΙ. Το υποερώτημα επιλέγει όλες εκείνες τις σειρές του πίνακα ASSIGNMENT όπου το WORKER_ID είναι το ίδιο με τη σειρά που θεωρείται από το κύριο ερώτημα και το BLDG_ID είναι 435. Εάν αυτό το σύνολο είναι κενό, τότε επιλέγεται η σειρά του εργαζόμενου που λαμβάνεται υπόψη από το κύριο ερώτημα, επειδή αυτό σημαίνει ότι αυτός ο εργαζόμενος δεν εργάζεται στο κτίριο 435.

Στη λύση μας, χρησιμοποιώντας ένα συσχετισμένο υποερώτημα. Αν χρησιμοποιήσουμε τον τελεστή IN αντί για NOT EXISTS, μπορούμε να τα καταφέρουμε με ένα μη συσχετισμένο υποερώτημα:

ΕΠΙΛΟΓΗ WORKER_ID

ΟΠΟΥ ΔΕΝ ΜΠΕΙ Ο ΕΡΓΑΤΗΣ_ID

(ΕΠΙΛΟΓΗ WORKER_ID

WHERE BLDG_ID = 435)

Αυτή η λύση είναι απλούστερη από τη λύση με τον τελεστή ΔΕΝ ΥΠΑΡΧΕΙ. Ένα φυσικό ερώτημα τίθεται γιατί χρειαζόμαστε ΥΠΑΡΧΕΙ και ΔΕΝ ΥΠΑΡΧΕΙ καθόλου. Η απάντηση είναι ότι το ΔΕΝ ΥΠΑΡΧΕΙ είναι ο μόνος τρόπος επίλυσης ερωτημάτων που περιέχουν τη λέξη "κάθε" στη συνθήκη. Τέτοια ερωτήματα επιλύονται στη σχεσιακή άλγεβρα χρησιμοποιώντας τη λειτουργία διαίρεσης και στον σχεσιακό λογισμό - χρησιμοποιώντας τον καθολικό ποσοτικοποιητή. Ακολουθεί ένα παράδειγμα ερωτήματος που περιέχει τη λέξη "κάθε" στη συνθήκη:

Αίτηση:Καταγράψτε τους εργάτες που έχουν ανατεθεί σε κάθε κτίριο.

Αυτή η ερώτηση μπορεί να εφαρμοστεί σε SQL χρησιμοποιώντας διπλή άρνηση. Θα επαναδιατυπώσουμε το ερώτημα για να συμπεριλάβουμε το διπλό αρνητικό:

Αίτηση:Καταγράψτε τους υπαλλήλους για τους οποίους Δενυπάρχει ένα κτίριο στο οποίο δεν έχουν ανατεθεί.

Έχουμε επισημάνει το διπλό αρνητικό. Είναι σαφές ότι αυτό το ερώτημα είναι λογικά ισοδύναμο με το προηγούμενο.

Τώρα θέλουμε να διαμορφώσουμε μια λύση σε SQL. Προκειμένου να γίνει ευκολότερη η κατανόηση της τελικής λύσης, θα δώσουμε πρώτα μια λύση σε ένα προκαταρκτικό πρόβλημα: το πρόβλημα της αναγνώρισης όλων των κτιρίων για τα οποία ο υποθετικός εργάτης, "1234" Δενανατεθεί.

(I) ΕΠΙΛΟΓΗ BLDG_ID

ΟΠΟΥ ΔΕΝ ΥΠΑΡΧΕΙ

ASIGNMENT.WORKER_ID = 1234)

Έχουμε προσθέσει ετικέτα σε αυτό το ερώτημα με ένα (I) όπως θα αναφερθούμε σε αυτό αργότερα. Εάν δεν υπάρχει κτίριο που να ικανοποιεί αυτό το αίτημα, τότε ο εργάτης 1234 εκχωρείται σε κάθε κτίριο και επομένως ικανοποιεί τις προϋποθέσεις του αρχικού αιτήματος. Για να λύσουμε το αρχικό ερώτημα, πρέπει να γενικεύσουμε το ερώτημα (I) από έναν συγκεκριμένο εργαζόμενο 1234 στη μεταβλητή WORKER_ID και να μετατρέψουμε αυτό το τροποποιημένο ερώτημα σε υποερώτημα του μεγαλύτερου ερωτήματος. Εδώ είναι μια λύση:

(II) ΕΠΙΛΟΓΗ WORKER_ID

ΟΠΟΥ ΔΕΝ ΥΠΑΡΧΕΙ

ΟΠΟΥ ΔΕΝ ΥΠΑΡΧΕΙ

WHERE ASIGNMENT.BLDG_ID = BUILDING.BLDG_ID ΚΑΙ

ASIGNMENT.WORKER_ID = WORKER.WORKER_ID)

Αποτέλεσμα:

ΤΑΥΤΟΤΗΤΑ ΕΡΓΑΤΟΥ

Σημειώστε ότι το δευτερεύον ερώτημα που ξεκινά από την τέταρτη γραμμή ερωτήματος (II) είναι πανομοιότυπο με το ερώτημα (I) στο οποίο το "1234" αντικαθίσταται από το WORKER.WORKER_ID. Το ερώτημα (II) μπορεί να διαβαστεί ως εξής:

Επιλέξτε WORKER_ID από το WORKER εάν δεν υπάρχει κτίριο στο οποίο δεν έχει εκχωρηθεί το WORKER_ID.

Αυτό ταιριάζει με τους όρους του αρχικού αιτήματος.

Βλέπουμε ότι ο τελεστής ΔΕΝ ΥΠΑΡΧΕΙ μπορεί να χρησιμοποιηθεί για τη διατύπωση των ερωτημάτων που απαιτούσαν μια λειτουργία διαίρεσης στη σχεσιακή άλγεβρα και έναν καθολικό ποσοτικοποιητή στον σχεσιακό λογισμό. Όσον αφορά την ευκολία χρήσης, ο τελεστής NOT EXISTS δεν παρέχει ειδικά πλεονεκτήματα, δηλαδή, τα ερωτήματα SQL που χρησιμοποιούν το NOT EXISTS δύο φορές δεν είναι ευκολότερα κατανοητά από τις λύσεις σχεσιακής άλγεβρας με λειτουργία διαίρεσης ή λύσεις σχεσιακού λογισμού με καθολικό ποσοτικοποιητή. Απαιτείται περισσότερη έρευνα για τη δημιουργία γλωσσικών κατασκευών που επιτρέπουν έναν πιο φυσικό τρόπο επίλυσης τέτοιων ερωτημάτων.

Ενσωματωμένες Λειτουργίες

Εξετάστε αυτούς τους τύπους ερωτήσεων:

Ποιες είναι οι μέγιστες και οι ελάχιστες ωριαίες χρεώσεις; Ποιος είναι ο μέσος αριθμός ημερών που εργάζονται οι εργαζόμενοι στο κτίριο 435; Ποιος είναι ο συνολικός αριθμός ημερών για εργασίες σοβάτισμα στο Κτίριο 312; Πόσες διαφορετικές ειδικότητες υπάρχουν;

Η απάντηση σε αυτές τις ερωτήσεις απαιτεί αθροιστικές συναρτήσεις που εξετάζουν πολλές σειρές πίνακα και παράγουν μια ενιαία τιμή. Η SQL έχει πέντε τέτοιες λειτουργίες, που ονομάζονται ενσωματωμένες συναρτήσεις ή συναρτήσεις συνόλου. Αυτές είναι οι συναρτήσεις SUM (άθροισμα), AVG (μέσος όρος), COUNT (count), MAX (μέγιστο) και MIN (ελάχιστο).

Ενσωματωμένη λειτουργία (συνάρτηση συνόλου). Στατιστική συνάρτηση που λειτουργεί σε πολλές σειρές: SUM (άθροισμα), AVG (μέσος όρος), COUNT (μέτρηση), MAX (μέγιστο), MIN (ελάχιστο).

Αίτηση:Ποιες είναι οι μέγιστες και οι ελάχιστες ωριαίες χρεώσεις;

SELECT MAX(HRLY_RATE), MIN(HRLY_RATE)

Αποτέλεσμα: 17.40, 8.20

MAX λειτουργίεςκαι MIN λειτουργούν σε μία στήλη πίνακα. Επιλέγουν τη μέγιστη ή την ελάχιστη τιμή, αντίστοιχα, από αυτήν τη στήλη. Η διατύπωση ερωτήματός μας δεν περιέχει ρήτρα WHERE. Για τα περισσότερα αιτήματα, αυτό μπορεί να μην ισχύει, όπως δείχνει το επόμενο παράδειγμά μας.

Αίτηση:Ποιος είναι ο μέσος αριθμός ημερών που εργάζονται οι εργαζόμενοι στο κτίριο 435;

ΕΠΙΛΟΓΗ AVG (NUM_DAYS)

WHERE BLDG_ID=435

Αποτέλεσμα: 12.33

Αίτηση:Ποιος είναι ο συνολικός αριθμός ημερών για εργασίες σοβάτισμα στο Κτίριο 312;

ΕΠΙΛΕΞΤΕ ΣΥΝΟΛΟ (NUM_DAYS)

ΑΠΟ ΑΠΟΣΤΟΛΗ, ΕΡΓΑΖΟΜΕΝΟΣ

WHERE WORKER.WORKER_ID = ASIGNMENT.WORKER_ID ΚΑΙ

SKILL_TYPE = "Γύψος" ΚΑΙ

Αποτέλεσμα: 27

Η λύση χρησιμοποιεί μια ένωση μεταξύ των πινάκων ASSIGNMENT και WORKER. Αυτό απαιτείται επειδή το SKILL_TYPE βρίσκεται στον πίνακα WORKER και το BLDG_ID στον πίνακα ASSIGNMENT.

Αίτηση:Πόσες διαφορετικές ειδικότητες υπάρχουν;

ΕΠΙΛΕΞΤΕ ΑΡΙΘΜΟΥΣ (ΔΙΑΚΡΙΤΗ_ΔΕΞΙΟΤΗΤΑ)

Αποτέλεσμα: 4

Εφόσον η ίδια ειδικότητα μπορεί να επαναληφθεί σε πολλές διαφορετικές σειρές, η λέξη-κλειδί DISTINCT (διαφορετική) πρέπει να χρησιμοποιηθεί σε αυτό το ερώτημα για να αποτρέψει το σύστημα να μετρήσει τον ίδιο τύπο ειδικότητας περισσότερες από μία φορές. Ο χειριστής DISTINCT μπορεί να χρησιμοποιηθεί με οποιαδήποτε από τις ενσωματωμένες λειτουργίες, αν και είναι, φυσικά, περιττός με τις λειτουργίες MAX και MIN.

ΔΙΑΚΡΙΤΗ. Ένας τελεστής που εξαιρεί διπλότυπες γραμμές.

Οι συναρτήσεις SUM και AVG θα πρέπει να χρησιμοποιούνται μόνο με αριθμητικές στήλες. Άλλες λειτουργίες μπορούν να χρησιμοποιηθούν τόσο με αριθμητικά όσο και με δεδομένα χαρακτήρων. Όλες οι συναρτήσεις εκτός από COUNT μπορούν να χρησιμοποιηθούν με υπολογισμένες εκφράσεις. Για παράδειγμα:

Αίτηση:Ποιος είναι ο μέσος εβδομαδιαίος μισθός;

ΕΠΙΛΟΓΗ AVG (40*HRLY_RATE)

Αποτέλεσμα: 509.14

Το COUNT μπορεί να αναφέρεται σε ολόκληρη τη σειρά, όχι μόνο σε μία στήλη :

Αίτηση: Πόσα κτίρια έχουν επίπεδο ποιότητας 3;

SELECT COUNT (*)

ΑΠΟ ΚΤΙΡΙΟ ΠΟΥ

Αποτέλεσμα: 3

Όπως δείχνουν όλα αυτά τα παραδείγματα, εάν υπάρχει μια ενσωματωμένη συνάρτηση στην εντολή SELECT, τότε δεν μπορεί να υπάρχει τίποτα άλλο σε αυτήν την εντολή SELECT. Η μόνη εξαίρεση σε αυτόν τον κανόνα είναι η ρήτρα GROUP BY, την οποία θα εξετάσουμε σε λίγο.

ΟΜΑΔΟΠΟΙΗΣΗ ΚΑΙ ΕΧΟΝΤΑΣ φράσεις

Στη διαχείριση, συχνά απαιτούνται στατιστικές πληροφορίες για κάθε ομάδα σε πολλές ομάδες. Για παράδειγμα, εξετάστε το ακόλουθο ερώτημα:

Αίτηση:Για κάθε διευθυντή, μάθετε τη μέγιστη ωριαία χρέωση μεταξύ των υφισταμένων του.

Για να λύσουμε αυτό το πρόβλημα, πρέπει να χωρίσουμε τους εργαζόμενους σε ομάδες ανάλογα με τους διευθυντές τους. Στη συνέχεια θα καθορίσουμε το μέγιστο στοίχημα σε κάθε ομάδα. Στην SQL γίνεται ως εξής:

ΟΜΑΔΑ ΚΑΤΑ SUPV_ID

Αποτέλεσμα:

SUPV_IDMAX (ΤΙΜΟΣ HRLY)

Κατά την επεξεργασία αυτού του ερωτήματος, το σύστημα διαιρεί πρώτα τις σειρές του πίνακα WORKER σε ομάδες σύμφωνα με τον ακόλουθο κανόνα. Οι σειρές τοποθετούνται στην ίδια ομάδα εάν και μόνο εάν έχουν το ίδιο SUPV_ID. Στη συνέχεια, η ρήτρα SELECT εφαρμόζεται σε κάθε ομάδα. Εφόσον υπάρχει μόνο μία τιμή SUPV_ID σε αυτήν την ομάδα, δεν υπάρχει ασάφεια SUPV_ID στην ομάδα. Για κάθε ομάδα, η πρόταση SELECT εξάγει το SUPV_ID και επίσης υπολογίζει και εξάγει την τιμή MAX(HRLY_RATE). Το αποτέλεσμα παρουσιάζεται παραπάνω.

Σε μια πρόταση SELECT με ενσωματωμένες συναρτήσεις, μπορούν να εμφανιστούν μόνο εκείνες οι στήλες που περιλαμβάνονται στον όρο GROUP BY. Σημειώστε ότι το SUPV_ID μπορεί να χρησιμοποιηθεί στην πρόταση SELECT επειδή περιλαμβάνεται στον όρο GROUP BY.

Φράση GROUP BY. Υποδεικνύει ότι οι σειρές πρέπει να χωριστούν σε ομάδες με κοινές τιμές των καθορισμένων στηλών.

Η ρήτρα GROUP BY σας επιτρέπει να εκτελέσετε ορισμένους σύνθετους υπολογισμούς. Για παράδειγμα, μπορεί να θέλουμε να μάθουμε τον μέσο όρο αυτών των μέγιστων προσφορών. Ωστόσο, οι υπολογισμοί με ενσωματωμένες συναρτήσεις είναι περιορισμένοι υπό την έννοια ότι δεν επιτρέπεται η χρήση ενσωματωμένων συναρτήσεων εντός άλλων ενσωματωμένων συναρτήσεων. Μια έκφραση λοιπόν σαν

AVG(MAX(HRLY_RATE))

απαγορευμένος. Η υλοποίηση ενός τέτοιου αιτήματος θα αποτελείται από δύο στάδια. Πρώτα πρέπει να βάλουμε τις μέγιστες προσφορές σε έναν νέο πίνακα και στο δεύτερο βήμα να υπολογίσουμε τον μέσο όρο τους.

Με την εντολή GROUP BY, μπορείτε να χρησιμοποιήσετε την εντολή WHERE:

Αίτηση:Για κάθε τύπο κτιρίου, μάθετε μέσο επίπεδοποιότητα μεταξύ κτιρίων κατάστασης 1.

SELECT TYPE, AVG (QLTY_LEVEL)

ΟΠΟΥ ΚΑΤΑΣΤΑΣΗ = 1

Αποτέλεσμα:

TYPEAVG (QLTY_LEVEL)

Κατάστημα 1

Κτίριο κατοικιών 3

Η πρόταση WHERE εκτελείται πριν από την εντολή GROUP BY. Επομένως, καμία ομάδα δεν μπορεί να περιέχει μια γραμμή που έχει κατάσταση διαφορετική από το 1. Οι σειρές Status 1 ομαδοποιούνται κατά TYPE και, στη συνέχεια, εφαρμόζεται μια ρήτρα SELECT σε κάθε ομάδα.

Φράση HAVING. Επιβάλλει όρους στις ομάδες.

Μπορούμε επίσης να εφαρμόσουμε συνθήκες σε ομάδες που δημιουργούνται από τον όρο GROUP BY. Αυτό γίνεται με την ρήτρα HAVING. Ας υποθέσουμε, για παράδειγμα, ότι αποφασίζουμε να εμπλουτίσουμε ένα από τα προηγούμενα ερωτήματα:

Αίτηση: Για κάθε διευθυντή που έχει περισσότερους από έναν υφισταμένους, μάθετε τη μέγιστη ωριαία αμοιβή μεταξύ των υφισταμένων του.

Μπορούμε να αντικατοπτρίσουμε αυτή τη συνθήκη με την κατάλληλη εντολή HAVING:

SELECT SUPV_ID, MAX(HRLY_RATE)

ΑΠΟ ΟΜΑΔΑ ΕΡΓΑΖΟΜΕΝΩΝ ΑΠΟ SUPV_ID

ΕΧΟΝΤΑΣ COUNT(*) > 1

Αποτέλεσμα:

SUPV_ID MAX(HRLY_RATE)

Η διαφορά μεταξύ των όρων WHERE και HAVING είναι ότι το WHERE ισχύει για σειρές ενώ το HAVING ισχύει για ομάδες.

Ένα ερώτημα μπορεί να περιέχει και έναν όρο WHERE και έναν όρο HAVING. Σε αυτήν την περίπτωση, η ρήτρα WHERE αξιολογείται πρώτα, επειδή αξιολογείται πριν από την ομαδοποίηση. Για παράδειγμα, εξετάστε την ακόλουθη τροποποίηση του προηγούμενου ερωτήματος:

Αίτηση: Για κάθε τύπο κτιρίου, μάθετε το μέσο επίπεδο ποιότητας μεταξύ των κτιρίων της κατάστασης 1. Λάβετε υπόψη μόνο εκείνους τους τύπους κτιρίων των οποίων το μέγιστο επίπεδο ποιότητας δεν υπερβαίνει το 3.

SELECT TYPE, AVG(QLTY_JLEVEL)

ΟΠΟΥ ΚΑΤΑΣΤΑΣΗ = 1

ΕΧΕΙ ΜΕΓΙΣΤΟ (QLTY_LEVEL)<= 3

Αποτέλεσμα:

TYPEAVG (QLTY_LEVEL)

Κατάστημα 1

Κτίριο κατοικιών 3

Σημειώστε ότι ξεκινώντας με την πρόταση FROM, οι φράσεις εκτελούνται με τη σειρά και στη συνέχεια εφαρμόζεται η ρήτρα SELECT. Για παράδειγμα, η ρήτρα WHERE εφαρμόζεται στον πίνακα BUILDING και όλες οι σειρές στις οποίες το STATUS δεν είναι 1 διαγράφονται. Οι υπόλοιπες σειρές ομαδοποιούνται κατά TYPE. όλες οι σειρές με την ίδια τιμή TYPE καταλήγουν στην ίδια ομάδα. Αυτό δημιουργεί πολλές ομάδες, μία για κάθε τιμή TYPE. Στη συνέχεια, η ρήτρα HAVING εφαρμόζεται σε κάθε ομάδα και αφαιρούνται εκείνες οι ομάδες των οποίων η μέγιστη τιμή επιπέδου ποιότητας είναι μεγαλύτερη από 3. Τέλος, η ρήτρα SELECT εφαρμόζεται στις υπόλοιπες ομάδες.

7. Ενσωματωμένες λειτουργίες και υποερωτήματα

Οι ενσωματωμένες συναρτήσεις μπορούν να χρησιμοποιηθούν μόνο σε μια πρόταση SELECT ή σε μια πρόταση HAVING. Ωστόσο, ένας όρος SELECT που περιέχει μια ενσωματωμένη συνάρτηση μπορεί να είναι μέρος ενός δευτερεύοντος ερωτήματος. Εξετάστε ένα παράδειγμα τέτοιου υποερωτήματος:

Αίτηση:Ποιος υπάλληλος έχει ωριαία αμοιβή πάνω από το μέσο όρο;

ΕΠΙΛΟΓΗ WORKER_NAME

WHERE HRLY_RATE >

(ΕΠΙΛΟΓΗ AVG(HRLY_RATE)

Αποτέλεσμα:

H. Columbus

Σημειώστε ότι το υποερώτημα δεν συσχετίζεται με το κύριο ερώτημα. Το υποερώτημα επιστρέφει ακριβώς μία τιμή - τη μέση ωριαία χρέωση. Το κύριο ερώτημα επιλέγει έναν εργαζόμενο μόνο εάν η προσφορά του είναι μεγαλύτερη από τον υπολογισμένο μέσο όρο.

Τα συσχετισμένα ερωτήματα μπορούν επίσης να χρησιμοποιούν ενσωματωμένες συναρτήσεις:

Ερώτημα: Ποιος από τους υπαλλήλους έχει ωρομίσθιο υψηλότερο από το μέσο ωρομίσθιο μεταξύ των υφισταμένων του ίδιου διευθυντή;

Σε αυτήν την περίπτωση, αντί να υπολογίσουμε μια μέση ωριαία χρέωση για όλους τους υπαλλήλους, πρέπει να υπολογίσουμε τη μέση ωριαία χρέωση για κάθε ομάδα εργαζομένων που αναφέρονται στον ίδιο διευθυντή. Επιπλέον, ο υπολογισμός μας πρέπει να γίνει ξανά για κάθε εργαζόμενο που λαμβάνεται υπόψη από το κύριο ερώτημα:

ΕΠΙΛΕΞΤΕ Α. WORKER_NAME

Η SQL σάς επιτρέπει να τοποθετείτε ερωτήματα μεταξύ τους. Συνήθως, ένα υποερώτημα επιστρέφει μια μεμονωμένη τιμή, η οποία ελέγχεται για να διαπιστωθεί εάν το κατηγόρημα είναι αληθές.

Τύποι συνθηκών αναζήτησης:
. Σύγκριση με αποτέλεσμα υποερωτήματος (=, >=)
. Έλεγχος εάν τα αποτελέσματα ενός δευτερεύοντος ερωτήματος ανήκουν (IN)
. Δοκιμή ύπαρξης (ΥΠΑΡΧΕΙ)
. Πολλαπλή (ποσοτική) σύγκριση (ΟΠΟΙΑΔΗΠΟΤΕ, ΟΛΑ)

Σημειώσεις για ένθετα ερωτήματα:
. Ένα υποερώτημα πρέπει να επιλέξει μόνο μία στήλη (εκτός από ένα υποερώτημα με κατηγόρημα ΥΠΑΡΧΕΙ) και ο τύπος δεδομένων αποτελέσματός του πρέπει να ταιριάζει με τον τύπο δεδομένων της τιμής που καθορίζεται στο κατηγόρημα.
. Σε ορισμένες περιπτώσεις, μπορείτε να χρησιμοποιήσετε τη λέξη-κλειδί DISTINCT για να διασφαλίσετε ότι λαμβάνετε μια ενιαία τιμή.
. Δεν μπορείτε να συμπεριλάβετε μια ρήτρα ORDER BY και UNION σε ένα δευτερεύον ερώτημα.
. Ένα υποερώτημα μπορεί να εμφανιστεί είτε στα αριστερά είτε στα δεξιά του όρου αναζήτησης.
. Τα δευτερεύοντα ερωτήματα μπορούν να χρησιμοποιούν συναρτήσεις συγκέντρωσης χωρίς όρο GROUP BY που επιστρέφει αυτόματα μια ειδική τιμή για οποιονδήποτε αριθμό σειρών, ένα ειδικό κατηγόρημα IN και εκφράσεις που βασίζονται σε στήλες.
. Όποτε είναι δυνατόν, οι ενώσεις πινάκων JOIN θα πρέπει να χρησιμοποιούνται αντί για δευτερεύοντα ερωτήματα.

Παραδείγματα για ένθετα ερωτήματα:

SELECT * FROM Orders WHERE SNum=(SELECT SNum FROM SalesPeople WHERE SName='Motika')
SELECT * FROM Orders WHERE SNum IN (SELECT SNum FROM SalesPeople WHERE City='London')
SELECT * FROM Orders WHERE SNum=(SELECT DISTINCT SNum FROM Orders WHERE CNum=2001)
SELECT * FROM Orders WHERE Amt>(SELECT AVG(Amt) FROM Orders WHERE Odate=10/04/1990)
SELECT * FROM Customer WHERE CNum=(SELECT SNum+1000 FROM SalesPeople WHERE SName='Serres')

2) Σχετικά υποερωτήματα

Στην SQL, μπορείτε να δημιουργήσετε υποερωτήματα με μια αναφορά πίνακα από ένα εξωτερικό ερώτημα. Σε αυτήν την περίπτωση, το υποερώτημα εκτελείται πολλές φορές, μία φορά για κάθε γραμμή πίνακα από το εξωτερικό ερώτημα. Επομένως, είναι σημαντικό το υποερώτημα να χρησιμοποιεί ένα ευρετήριο. Το υποερώτημα μπορεί να αναφέρεται στον ίδιο πίνακα με τον εξωτερικό. Εάν το εξωτερικό ερώτημα επιστρέφει έναν σχετικά μικρό αριθμό σειρών, τότε το συσχετισμένο υποερώτημα θα έχει ταχύτερη απόδοση από το άσχετο. Εάν το υποερώτημα επιστρέψει μικρό αριθμό σειρών, τότε το συσχετισμένο ερώτημα θα εκτελείται πιο αργά από το άσχετο.

Παραδείγματα για σχετικά δευτερεύοντα ερωτήματα:

SELECT * FROM SalesPeople Main WHERE 1(SELECT AVG(Amt) FROM Orders O2 WHERE O2.CNum=O1.CNum) //επιστρέφει όλες τις παραγγελίες μεγαλύτερες από τη μέση τιμή παραγγελίας για αυτόν τον πελάτη

3) ΥΠΑΡΧΕΙ κατηγόρημα

Μορφή σύνταξης: ΥΠΑΡΧΕΙ ()

Το κατηγόρημα παίρνει το υποερώτημα ως όρισμα και αξιολογεί ως αληθές εάν το υποερώτημα έχει έξοδο, διαφορετικά αξιολογείται ως ψευδές. Το υποερώτημα εκτελείται μία φορά και μπορεί να περιέχει πολλές στήλες, καθώς οι τιμές τους δεν ελέγχονται, αλλά το αποτέλεσμα της παρουσίας σειρών απλώς διορθώνεται.

Σημειώσεις για το κατηγόρημα ΥΠΑΡΧΕΙ:
. Το EXISTS είναι ένα κατηγόρημα που επιστρέφει TRUE ή FALSE και μπορεί να χρησιμοποιηθεί μόνο του ή με άλλες δυαδικές εκφράσεις.
. Το EXISTS δεν μπορεί να χρησιμοποιήσει συγκεντρωτικές συναρτήσεις στο υποερώτημά του.
. Σε συσχετισμένα (σχετικά, εξαρτημένα - Συσχετισμένα) υποερωτήματα, το κατηγόρημα EXISTS εκτελείται για κάθε γραμμή του εξωτερικού πίνακα.
. Μπορείτε να συνδυάσετε το κατηγόρημα EXISTS με ενώσεις πινάκων.

Παραδείγματα για το κατηγόρημα EXISTS:

SELECT * FROM Customer WHERE EXISTS(SELECT * FROM Customer WHERE City='San Jose') - επιστρέφει όλους τους πελάτες εάν κάποιος από αυτούς ζει στο San Jose.
SELECT DISTINCT SNum FROM Customer First WHERE NOT EXISTS (SELECT * FROM Customer Send WHERE Send.SNum=First.SNum ΚΑΙ Send.CNumFirst.CNum) - Επιστρέφει τον αριθμό των πωλητών που εξυπηρέτησαν μόνο έναν πελάτη.
SELECT DISTINCT F.SNum, SName, F.City FROM SalesPeople F, Customer S WHERE EXISTS (SELECT * FROM Customer T WHERE S.SNum=T.SNum AND S.CNumT.CNum AND F.SNum=S.SNum) - επιστρέφει αριθμούς, ονόματα και πόλεις διαμονής όλων των πωλητών που εξυπηρέτησαν αρκετούς αγοραστές.
SELECT * FROM SalesPeople Frst WHERE EXISTS (SELECT * FROM Customer Send WHERE Frst.SNum=Send.SNum AND 1

4) Κατηγορήματα ποσοτικής σύγκρισης

Μορφή σύνταξης: (=|>|=|) ΟΠΟΙΑΔΗΠΟΤΕ|ΟΛΑ ()

Αυτά τα κατηγορήματα χρησιμοποιούν ένα υποερώτημα ως όρισμα, ωστόσο, σε σύγκριση με το κατηγόρημα EXISTS, χρησιμοποιούνται σε συνδυασμό με σχεσιακά κατηγορήματα (=,>=). Υπό αυτή την έννοια, είναι παρόμοια με το κατηγόρημα IN, αλλά ισχύουν μόνο για υποερωτήματα. Το πρότυπο επιτρέπει τη χρήση της λέξης-κλειδιού SOME αντί για ANY, αλλά δεν την υποστηρίζουν όλα τα DBMS.

Σημειώσεις σχετικά με τα κατηγορήματα σύγκρισης:
. Το κατηγόρημα ALL αξιολογείται σε TRUE εάν κάθε τιμή που επιλέγεται κατά την εκτέλεση του υποερωτήματος ικανοποιεί τη συνθήκη που καθορίζεται στο κατηγόρημα του εξωτερικού ερωτήματος. Τις περισσότερες φορές χρησιμοποιείται με ανισότητες.
. Το κατηγόρημα ANY αξιολογείται σε TRUE εάν τουλάχιστον μία τιμή που επιλέχθηκε κατά την εκτέλεση του υποερωτήματος ικανοποιεί τη συνθήκη που καθορίζεται στο κατηγόρημα του εξωτερικού ερωτήματος. Τις περισσότερες φορές χρησιμοποιείται με ανισότητες.
. Εάν το υποερώτημα δεν επιστρέφει σειρές, τότε το ALL παίρνει αυτόματα την τιμή TRUE (θεωρείται ότι πληρούται η συνθήκη σύγκρισης), και για ΟΠΟΙΑΔΗΠΟΤΕ - FALSE.
. Εάν η σύγκριση δεν είναι ΑΛΗΘΕΙΑ για καμία σειρά και υπάρχουν μία ή περισσότερες μηδενικές σειρές, τότε το ANY επιστρέφει ΑΓΝΩΣΤΟ.
. Εάν η σύγκριση δεν είναι FALSE για οποιαδήποτε σειρά και υπάρχουν μία ή περισσότερες μηδενικές σειρές, τότε ALL επιστρέφει ΑΓΝΩΣΤΟ.

Παραδείγματα για το κατηγόρημα ποσοτικής σύγκρισης:

SELECT * FROM SalesPeople WHERE City=ANY(ΕΠΙΛΟΓΗ Πόλης ΑΠΟ Πελάτη)
SELECT * FROM Orders WHERE Amt ALL(SELECT Rating FROM Customer WHERE City='Rome')

5) Κατηγόρημα μοναδικότητας

ΜΟΝΑΔΙΚΟ|ΔΙΑΚΡΙΤΙΚΟ ()

Το κατηγόρημα χρησιμοποιείται για τον έλεγχο της μοναδικότητας (απουσία διπλότυπων) στην έξοδο του υποερωτήματος. Επιπλέον, στο κατηγόρημα UNIQUT, οι σειρές με τιμές NULL θεωρούνται μοναδικές και στο κατηγόρημα DISTINCT, δύο μηδενικές τιμές θεωρούνται ίσες μεταξύ τους.

6) Ταίριασμα κατηγορήματος

ΑΓΩΝΑΣ ()

Το κατηγόρημα MATCH ελέγχει εάν η τιμή μιας συμβολοσειράς ερωτήματος θα ταιριάζει με την τιμή οποιασδήποτε συμβολοσειράς που επιστρέφεται από το υποερώτημα. Αυτό το υποερώτημα διαφέρει από τα κατηγορήματα IN και ΚΑΠΟΙΑ, καθώς σας επιτρέπει να επεξεργάζεστε "μερικές" (PARTIAL) αντιστοιχίσεις που μπορεί να προκύψουν μεταξύ σειρών που έχουν μέρος των τιμών NULL.

7) Αιτήματα στην ενότητα ΑΠΟ

Στην πραγματικότητα, είναι αποδεκτή η χρήση υποερωτήματος όπου επιτρέπεται μια αναφορά πίνακα.

SELECT CName, Tot_Amt FROM Customer, (SELECT CNum, SUM(Amt) AS Tot_Amt FROM Orders GROUP BY CNum) WHERE City='London' AND Customer.CNum=Orders.CNum
//υποερώτημα επιστρέφει το συνολικό ποσό των παραγγελιών που υποβλήθηκαν από κάθε αγοραστή από το Λονδίνο.

8) Αναδρομικά ερωτήματα

ΜΕ ΑΝΑΔΡΟΜΙΚΟ
Ε1 ΩΣ ΕΠΙΛΟΓΗ … ΑΠΟ … ΠΟΥ…
Ε2 ΩΣ ΕΠΙΛΟΓΗ … ΑΠΟ … ΠΟΥ…




Μπλουζα