The Wayback Machine - https://web.archive.org/web/20260308205334/https://www.scribd.com/document/635356072/%CE%92%CE%91%CE%A3%CE%95%CE%99%CE%A3-%CE%94%CE%95%CE%94%CE%9F%CE%9C%CE%95%CE%9D%CE%A9%CE%9D-%CE%91%CE%9D%CE%A4%CE%A9%CE%9D%CE%99%CE%91%CE%94%CE%97%CE%A3-%CE%9D%CE%99%CE%9A%CE%9F%CE%9B%CE%91%CE%9F%CE%A3-%CE%A0%CE%91%CE%9D%CE%95%CE%A0%CE%99%CE%A3%CE%A4%CE%97%CE%9C%CE%99%CE%9F-%CE%99%CE%A9%CE%91%CE%9D%CE%9D%CE%99%CE%9D%CE%A9%CE%9D
0% found this document useful (0 votes)
261 views150 pages

ΒΑΣΕΙΣ ΔΕΔΟΜΕΝΩΝ ΑΝΤΩΝΙΑΔΗΣ ΝΙΚΟΛΑΟΣ ΠΑΝΕΠΙΣΤΗΜΙΟ ΙΩΑΝΝΙΝΩΝ

ΠΛΗΡΟΦΟΡΙΚΗ ΒΑΣΕΙΣ ΔΕΔΟΜΕΝΩΝ SQL

Uploaded by

pliroforiki2
Copyright
© Public Domain
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
261 views150 pages

ΒΑΣΕΙΣ ΔΕΔΟΜΕΝΩΝ ΑΝΤΩΝΙΑΔΗΣ ΝΙΚΟΛΑΟΣ ΠΑΝΕΠΙΣΤΗΜΙΟ ΙΩΑΝΝΙΝΩΝ

ΠΛΗΡΟΦΟΡΙΚΗ ΒΑΣΕΙΣ ΔΕΔΟΜΕΝΩΝ SQL

Uploaded by

pliroforiki2
Copyright
© Public Domain
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

ΒΑΣΕΙΣ ΔΕΔΟΜΕΝΩΝ

Νίκος Αντωνιάδης

Τι είναι Βάση Δεδομένων;


• Ποιος έχει βάση δεδομένων;
• Εφορία
• ΕΦΚΑ
• Γραμματεία
• eBay
• Ηλεκτρονικό κατάστημα

• ΟΛΟΙ έχουν ΒΔ, από πολύ μικρές (ένα ηλεκτρονικό κατάστημα με 100
προϊόντα) έως πολύ μεγάλες (taxisnet, Amazon, Google, …)
Περιγραφή/ορισμός
• Δεδομένα αποθηκευμένα και ΟΡΓΑΝΩΜΕΝΑ
• Χαρακτηριστικά για κάθε αντικείμενο
• Λογισμικό εξειδικευμένο για αναζήτηση

• Σύστημα Διαχείρισης Βάσης Δεδομένων

Σύστημα Διαχείρισης Βάσης Δεδομένων

ΣΔΒΔ

ΒΔ
Σύστημα Βάσεων
Δεδομένων
Γιατί τόση φασαρία?
• Τα ΣΔΒΔ είναι παντού

• Εφορία
• Αγορές προϊόντων
• ΑΤΜ
• Πιστωτικές κάρτες
• Γραμματεία Τμήματος

Γιατί τόση φασαρία?


• Facebook
• Amazon
• Ebay
• AirBnB
Γιατί τόση φασαρία?
Συνεχής παραγωγή data

• Κινητή τηλεφωνία
• Συστήματα καμερών (κάμερες τροχαίας, εναέρια κίνηση,
κοινωνικά δίκτυα)
• Καταγραφή στοιχείων
• Μετεωρολογικά
✓Κίνηση στους δρόμους
✓Εφαρμογές άθλησης
✓Εφαρμογές υγείας (φορέσιμες συσκευές, τηλεϊατρική)

Τι θα δούμε αυτό το εξάμηνο

▪ Σχεδιασμός Βάσης Δεδομένων


▪ Εργαλεία χειρισμού δεδομένων (SQL)
▪ Βέλτιστος σχεδιασμός / υλοποίηση ΒΔ

8
Δημιουργία ΒΔ: ένα (όχι και τόσο)
σύνθετο έργο
Μοντελοποίηση

• Κατάστρωση μοντέλου
• Στο χαρτί!
• Κακό μοντέλο → αποτυχία
• Μοντέλο Οντοτήτων/Συσχετίσεων (Entity-Relationship model)

Προγραμματισμός/υλοποίηση
• Χρήση εμπορικού πακέτου
• Ανάπτυξη προγραμματιστικών εργαλείων
• Ανάπτυξη διεπαφής

Μοντελοποίηση

Σχήμα (database schema): η περιγραφή της δομής της


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

Μοντέλο Δεδομένων: ένα σύνολο από έννοιες (δομικά


στοιχεία) που μπορούν να χρησιμοποιηθούν για την
περιγραφή της δομής της πληροφορίας

Βάσεις Δεδομένων 2017-2019 Ευαγγελία Πιτουρά 10


Σκοπός ΒΔ
• Παράδειγμα: σύστημα πληροφοριών τράπεζας
• Καταθέσεις: αριθμος λογαριασμού, υπολοιπο , κάτοχος
• Δάνεια: αρ. δανείου, κεφάλαιο, κάτοχος, εγγυητης
• Στοιχεία πελατών : ονομα, ΑΦΜ, τηλέφωνο, διεύθυνση, λογαριασμοί,
δάνεια

• Σύστημα αρχείων (όχι ΒΔ)


• Σύνολο ρουτινών
• Ρουτίνα πίστωσης / χρέωσης λογαριασμού
• Ρουτίνα δημιουργίας λογαριασμού
• Ρουτίνα δημιουργίας μηνιαίων αναφορών

Ιστορία
Δεκαετία του 1950
Κάρτες και ταινίες (σειριακή επεξεργασία) – Batch processing

Αρχή του 1960


Γενικευμένη χρήση δίσκων
πρώτο γενικού-σκοπού ΣΔΒΔ (διαχωρισμός της λειτουργικότητας διαχείρισης
δεδομένων από τις εφαρμογές): Integrated Data Store (GE)
Charles Bachman (Recipient of the 1st Turing Award, 1973)
network data model (δικτυωτό)
Τέλη του 1960
Information Management System (IMS) IBM
hierarchical data model (Ιεραρχικό)
SABRE Airline Reservation System (AA+IBM, travelocity!!)

12
Ιστορία
Peter P. Chen

1970
Edgar Codd (IBM, San Jose) σχεσιακό μοντέλο δεδομένων (relational data model)
(Recipient of the Turing Award, 1981)
Ερευνητικά Προγράμματα: System R, INGRES - Γλώσσες: SEQUEL, QBE,
QUEL
Δεκαετία του 1980
SQL (μέρος του System R)
transaction management (Jim Gray, Turing Award, 1999)
υποσημείωση: Jim Gray gone missing
[Τάσεις: αντικειμενοστραφή, αρχιτεκτονική πελάτη-εξυπηρέτη,
κατανεμημένες, έμπειρα]

13

Ιστορία
Δεκαετία του 1990
εμπορικά αντικειμενοστραφή συστήματα
[Τάσεις: πολυβάσεις, χωρικές & χρονικές, πολυμέσα,
συμπερασματικές, αποθήκες δεδομένων (αναλυτική
επεξεργασία), προγραμματισμό πόρων της επιχείρησης (ERP –
Enterprise Resource Planning) και της διαχείρισης τους
(MRP – Management Resource Planning), Internet]
Δεκαετία του 2000
Σύστημα Διαχείρισης Χρωμοσωμάτων (Human Genome Project)
Σύστημα Παρατήρησης της Γης (Earth Observation System)

M. Stonebraker, Turing Award 2014


Ingress, Postgress, entrepreneur, ..
1M from Google

14
Ιστορία
Σήμερα, 2004 - …
o Μεγάλος όγκος δεδομένων (BIG DATA)
o Αλλαγές σε υλικό (επεξεργαστές με πολλούς πυρήνες, κλπ)
o cloud computing
o data lakes

o AI & ML

Κίνηση NoSQL
MapReduce (2004) και Bigtable (2006) by Google, Dynamo (2007) by Amazon
Hadoop (βασισμένο στο MapReduce, 2006), Cassandra (επηρεασμένη από Bigtable και Dynamo papers) και
MongoDB (2009)

Κίνηση NotOnlySQL
Join! SQL interfaces πάνω στο Hadoop (και αργότερα στη Spark)
Κίνηση NewSQL
Spanner (2012) by Google PostgreSQL 10 (native support for JSON, κλπ)

15

Τι είναι Βάση Δεδομένων;


• Είναι αρχείο;
• Είναι κάτι σαν το Word;
• Είναι κάτι σαν το Excel;

• Ποια είναι η διαφορά με ένα αρχείο (οποιοδήποτε) που έχει


τα ίδια δεδομένα ;
Αρχεία αποθήκευσης
• Πλεονασμός δεδομένων
Πίνακας στοιχείων
Όνομα ΑΔΤ ΑΦΜ Διεύθυνση
Παππάς ΑΒ475859 012345678 Βενιζέλου 12, Αρτα
Πέτρου ΑΕ069584 320195849
Νικολάου ΑΒ392020 039283742 Δωδώνης 34, Ιωάννινα

Πίνακας λογαριασμών
Όνομα ΑΔΤ ΑΦΜ Διεύθυνση Αρ. λογ Υπόλοιπο
Παππάς ΑΒ475859 012345678 Βενιζέλου 12, Αρτα Α123456 324.00
Πέτρου ΑΕ069584 320195849 Β324354 1258,99

Υπάρχει πρόβλημα;
• Τα δεδομένα επαναλαμβάνονται
Πλεονασμός (redundancy)

• Αν θέλουμε να συνδέσουμε τους πίνακες, πρέπει να γίνει


προγραμματιστικά
• Αν αλλάξει κάτι, πχ μια διεύθυνση, πρέπει η αλλαγή να γίνει
σε όσα αρχεία αυτή υπάρχει → λάθη (σκόπιμα ή τυχαία)
Ασυνέπεια (inconsistency)
Δυσκολίες πρόσβασης
• Ζητείται η λίστα των πελατών της Αθήνας → ρουτίνα
• Ζητείται η λίστα των πελατών της Λάρισας και του Βόλου
→ ρουτίνα ή τροποποίηση της προηγούμενης
• Ζητείται η λίστα των πελατών όλης της Ελλάδας → ρουτίνα
• Ζητείται η λίστα λογαριασμών με υπόλοιπο πάνω από
10000 → ρουτίνα
• Ζητείται η λίστα λογαριασμών με υπόλοιπο μεταξύ 5000 και
15000 → ρουτίνα

Δυσκολίες πρόσβασης
• Μειονεκτήματα
• Συνεχής ανάπτυξη νέου λογισμικού
• Τροποποιήσεις από διάφορους προγραμματιστές
• Αδύνατον να προβλεφθούν όλα τα πιθανά ερωτήματα

Ανάγκη για καλύτερη οργάνωση των δεδομένων


Ακεραιότητα
• Τύποι δεδομένων
• Αριθμοί
• Δεκαδικοί
• Δυαδικές (true/false)
• Ημερομηνία
• Format
• Δεν υπάρχει δυνατότητα πρόβλεψης συγκεκριμένης
μορφοποίησης

Ακεραιότητα
• Περιορισμοί:
• Υπόλοιπο λογαριασμού τουλάχιστον 0
• Ημερομηνίες μόνο νόμιμες (όχι 30/2/2020)
•…
• Το αρχείο δεν μπορεί να κάνει τέτοιους ελέγχους

Ακεραιότητα (integrity)
Αναγκαιότητα η ΒΔ
• Τα παραδοσιακά συστήματα έχουν πολύ λίγες δυνατότητες
• Ανάγκη διασύνδεσης
• Ανάγκη βέλτιστης αποθήκευσης δεδομένων
• Ανάγκη γρήγορης και αξιόπιστης συνεργασίας

Παράδειγμα: Σύστημα γραμματείας

Απαιτήσεις χρήστη (user requirements)

• Καθηγητές: όνομα, αντικείμενο, τηλέφωνο,


φοιτητές που επιβλέπει, μαθήματα
• Φοιτητές: μαθήματα, όνομα, τηλεφωνο,
εξάμηνο, βαθμοί
• Μαθήματα: κωδικός, όνομα, ώρες, φοιτητές
Για ποιον υπάρχει η ΒΔ?
• Καθημερινοί χρήστες (εκατοντάδες εκατομμύρια)
• Προγραμματιστές
• Σχεδιαστές βάσεων δεδομένων
• Admins
• Δημιουργοί ΣΔΒΔ

25

Διεπαφές
front ends εφαρμογών Διεπαφή SQL
Web forms
SQL

ΣΔΒΔ

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

▪ Βασιζόμενες σε μενού (κατάλογο από επιλογές), γραφικών,


Βασιζόμενες σε φόρμες, φυσικής γλώσσας, για παραμετρικούς
χρήστες, για το ΔΒΔ
26
Διαγράμματα E-R

Πώς βλέπουμε μια βάση δεδομένων


Επίπεδα αναπαράστασης
• Αφαίρεση (abstraction): μοντέλο σχεδίασης
• Μόνο τα λογικά στοιχεία
• Επίπεδα αναπαράστασης
• Φυσικό (physical)
• Εννοιολογικό (conceptual)
• Εποπτικό (view)

Επίπεδα αναπαράστασης
• Φυσικό:
• Δίσκος
• Αποθήκευση των δεδομένων
• Κατάτμηση που δεν φαίνεται
• Μη κατανοητό στους περισσότερους (ακόμα και μηχανικών)
• Εννοιολογικό:
• Λογικές σχέσεις μεταξύ αντικειμένων, δεδομένων, περιορισμών
• Κατανοητό από τους περισσότερους
• Σημαντικό να κατανοήσουμε αυτό το επίπεδο
• Σχεδίαση στο «χαρτί»
Επίπεδα αναπαράστασης
• Εποπτικό:
• Εφαρμογές
• Interface
• Διάφορες πλευρές για διαφορετικούς χρήστες
• Όχι πλήρης εποπτεία (δεν είναι απαραίτητο)
• Σημαντικό για την σημερινή εξάπλωση των ΣΔΒΔ

Λογικά Μοντέλα
• Μεσαίο επίπεδο στο διάγραμμα
• Διαφορετικές φιλοσοφίες
• Λογικά μοντέλα αντικειμένων
• Λογικά μοντέλα εγγραφών
• Μοντέλα φυσικών δεδομένων
Λογικά Μοντέλα
• Το μοντέλο οντοτήτων-συσχετίσεων (Entity-Relationship Model)
• Το αντικειμενοστραφές μοντέλο (object-oriented model)
• Το δυαδικό μοντέλο
• Το μοντέλο σημασιολογικών δεδομένων
• Το πληροφοριακό μοντέλο
• Το μοντέλο λειτουργικών δεδομένων

Στην εισαγωγή μας στο μάθημα, είναι σημαντικό να δούμε το πρώτο


μοντέλο, που δίνει σημαντική εποπτεία στον σχεδιαστή

Μοντέλο Οντοτήτων- Συσχετίσεων


(Entity- Relationship Model)
• Οντότητα: αντικείμενο
• Διακριτό από άλλα: «στέκεται μόνο του»
• Με δικά του χαρακτηριστικά: ιδιότητες
• Συσχέτιση: σύνδεση
• Έκφραση πραγματικής σχέσης
• Μπορεί να έχει και δικά της χαρακτηριστικά

• Όμοια αντικείμενα: σύνολο οντοτήτων


• Όμοιες συσχετίσεις: σύνολο συσχετίσεων
Μοντέλο Οντοτήτων- Συσχετίσεων
αναπαράσταση
• Οντότητα: ορθογώνιο
• Φυσιολογικά δίνεται κάποιο όνομα
• Χαρακτηριστικά: έλλειψη
• Συσχέτιση: ρόμβος
• Φυσιολογικά δίνεται κάποιο όνομα
• Σύνδεση με τις οντότητες: γραμμές

Μοντέλο Οντοτήτων- Συσχετίσεων


Παράδειγμα

• Σύνδεση δύο οντοτήτων


• Χαρακτηριστικά: τι ιδιαίτερο έχουν αυτά? (άσκηση)
Λογικά μοντέλα εγγραφών
• Εγγραφές: δεδομένα σε σταθερή μορφή
• Θέσεις πίνακα
• Συγκεκριμένα πεδία: μήκος, τύπος
• Σχεσιακό
• Δικτυακό
• Ιεραρχικό

Σχεσιακό μοντέλο
Σχεσιακό μοντέλο
• Πίνακες
• Διακριτά ονόματα
• Στήλες-γραμμές
• Όλες οι συσχετίσεις μπορούν να φανούν με επισκόπηση

Στιγμιότυπα / Σχήματα
• Σχήμα: λογική αναπαράσταση
• Συνολική σχεδίαση
• Χαρακτηριστικά και περιορισμοί
• Ισχύουν σχεδόν πάντα (για πολύ χρόνο)

• Στιγμιότυπο: φωτογραφία της στιγμής


• Δεδομένα τρέχοντα
• Συμφωνούν με το σχήμα
• Δεν υπαγορεύουν το σχήμα
Οντότητα
• Τραπεζικό σχήμα
• Πελάτης: ον-πελ, ΑΦΜ, οδός, πολ-πελ, αρ-λογ(?)
• Λογαριασμός: αρ-λογ, υπόλ, ον-πελ(?)

Βάση τράπεζας
• Branch (κατάστημα), το σύνολο όλων των καταστημάτων της τράπεζας, με
χαρακτηριστικά br-name (όνομα καταστήματος), br-city (πόλη καταστήματος),
assets (περιουσία).
• Customer (Πελάτης), το σύνολο όλων των ατόμων που έχουν κάποιο λογαριασμό
στην τράπεζα, με χαρακτηριστικά cust-name (όνομα-πελάτη), AFM (ΑΦΜ), street
(οδός), cust-city (πόλη-πελάτη).
• Employee (Υπάλληλος), το σύνολο όλων των ατόμων που δουλεύουν στην
τράπεζα, με χαρακτηριστικά empl-name (όνομα-υπαλλήλου) και phone (αριθ.
τηλεφώνου).
• Account (Λογαριασμός), το σύνολο όλων των λογαριασμών της τράπεζας, με
χαρακτηριστικά acc-number (αριθμός λογαριασμού) και balance (υπόλοιπο)
• Transaction (συναλλαγή), το σύνολο όλων των συναλλαγών που γίνονται σε της
τράπεζας, με χαρακτηριστικά trans-number (αριθμός συναλλαγής), date
(ημερομηνία) και amount (ποσό).
Διαγράμματα E-R
Συσχετίσεις και σύνολα συσχετίσεων

Βάση τράπεζας
• Branch (κατάστημα), το σύνολο όλων των καταστημάτων της τράπεζας, με
χαρακτηριστικά br-name (όνομα καταστήματος), br-city (πόλη καταστήματος),
assets (περιουσία).
• Customer (Πελάτης), το σύνολο όλων των ατόμων που έχουν κάποιο λογαριασμό
στην τράπεζα, με χαρακτηριστικά cust-name (όνομα-πελάτη), AFM (ΑΦΜ), street
(οδός), cust-city (πόλη-πελάτη).
• Employee (Υπάλληλος), το σύνολο όλων των ατόμων που δουλεύουν στην
τράπεζα, με χαρακτηριστικά empl-name (όνομα-υπαλλήλου) και phone (αριθ.
τηλεφώνου).
• Account (Λογαριασμός), το σύνολο όλων των λογαριασμών της τράπεζας, με
χαρακτηριστικά acc-number (αριθμός λογαριασμού) και balance (υπόλοιπο)
• Transaction (συναλλαγή), το σύνολο όλων των συναλλαγών που γίνονται σε της
τράπεζας, με χαρακτηριστικά trans-number (αριθμός συναλλαγής), date
(ημερομηνία) και amount (ποσό).
Συσχέτιση
CustAcct

Customer
Account

Συσχέτιση
• Σύνδεση μεταξύ οντοτήτων
• Συνήθως δύο, μπορεί και περισσότερες
• Μπορούμε να αναλύσουμε οποιαδήποτε σχέση με >2 οντότητες σε
περισσότερες σχέσεις μεταξύ δύο οντοτήτων η κάθε μία
• Δεν μας ενδιαφέρει στα πλαίσια της εισαγωγής του μαθήματος
• Παράδειγμα: Πελάτες σχετίζονται με λογαριασμούς
• Προφανής συσχέτιση: πελάτης έχει λογαριασμό
• Μπορεί να είναι και κάτι άλλο: πελάτης συνδέει την κάρτα με λογαριασμό
Συσχέτιση / οντότητα?
• Δεν είναι απολύτως ξεκάθαρο αν πρέπει να είναι το ένα ή το άλλο
• Μπορεί να αποφασίσουμε ότι κάποιο χαρακτηριστικό είναι οντότητα
από μόνο του

Employee (emp-name, phone)


• Οι υπάλληλοι είναι σίγουρα οντότητα
• Μήπως είναι και το phone? Σκεφτείτε για λίγο
• Τι θα σήμαινε να είναι οντότητα το phone (phone-no, office) ?
• Τι θα σκεφτόμασταν αν βλέπαμε να συμβαίνει αυτό στην ολοκληρωμένη
σχεδίαση?

Συσχέτιση / οντότητα?
• Αν το phone μείνει ως οντότητα,

=> Ενδιαφέρει να είναι αυτοδύναμο

• Δεν χρειάζεται να έχει δοθεί ο αριθμός σε υπάλληλο


• Ξέρουμε τη λίστα των διαθέσιμων τηλεφώνων
• Τώρα θέλουμε και μια συσχέτιση μεταξύ Employee και Phone
Συσχέτιση / οντότητα?
• Γενική παρατήρηση:
Δεν υπάρχει μία μοναδική λύση
• Εξαρτάται πάντα από τις προδιαγραφές
• Πολλές φορές ο σχεδιαστής συνδιαμορφώνει

Περιορισμοί συσχετίσεων
Περιορισμοί συσχετίσεων

Ποια είναι η διαφορά???

Περιορισμοί συσχετίσεων
• Υπενθύμιση: σχήμα vs στιγμιότυπο

• Η πρώτη περίπτωση: φαίνεται σαν ένα προς ένα


• Από κάθε κουκίδα (υπενθύμιση: τι είναι η κουκίδα σε μια ΒΔ?) ξεκινάει το
πολύ μία γραμμή
• Η δεύτερη περίπτωση: φαίνεται σαν ένα προς πολλά
• Από κάθε κουκίδα αριστερά μπορούν να ξεκινάνε πολλές γραμμές
• Σε κάθε κουκίδα δεξιά, φαίνεται να καταλήγει μία γραμμή
Περιορισμοί συσχετίσεων
• Προσοχή: δεν είμαστε βέβαιοι για όλα αυτά

• Για το «ένα» δεν είμαστε ποτέ σίγουροι


• Για το «πολλά» ξέρουμε ότι δεν μπορεί να είναι ένα
• Ελέγχουμε και τις δύο πλευρές

Περιορισμοί συσχετίσεων

Πολλά προς ένα


Περιορισμοί συσχετίσεων

Πολλά προς πολλά

Παράδειγμα
CustAcct
• Δεν έχουμε κοινούς λογαριασμούς ΚΑΙ όχι πάνω από ένας
1-προς-1

• Έχουμε κοινούς λογαριασμούς ΚΑΙ όχι πάνω από ένας


N-προς-1

• Έχουμε κοινούς λογαριασμούς ΚΑΙ μπορεί και πάνω από ένας


Μ-προς-Ν
Παράδειγμα
Μπορεί να είναι πολλές οι διαφορετικές επιλογές
Εξαρτάται από το πρόβλημα
Πρέπει να το διευκρινίζουμε
Αλλά
Αν δεν υπάρχει ο περιορισμός, δεν τον βάζουμε

Πληθικότητα συσχέτισης στο E-R


Πλευρά του «1»: Βελάκι

Σχέση πολλά-προς-1
Πληθικότητα συσχέτισης στο E-R
Πλευρά του «1»: Βελάκι

Σχέση 1-προς-1

Κλειδιά
• Χαρακτηριστικό
• Μοναδική τιμή
• Όχι κενό
• Εκπροσωπεί την κάθε εγγραφή
• Βοηθάει πάρα πολύ στην αναζήτηση
• Δεν είναι απαραίτητο, αλλά μόνο τρελός δεν θα όριζε
• Μπορεί να είναι ένα ή περισσότερα χαρακτηριστικά (όσα
χρειάζονται)
Ρόλοι – ασθενής οντότητα

Βάση τράπεζας
• Branch (κατάστημα), το σύνολο όλων των καταστημάτων της τράπεζας, με
χαρακτηριστικά br-name (όνομα καταστήματος), br-city (πόλη καταστήματος),
assets (περιουσία).
• Customer (Πελάτης), το σύνολο όλων των ατόμων που έχουν κάποιο λογαριασμό
στην τράπεζα, με χαρακτηριστικά cust-name (όνομα-πελάτη), AFM (ΑΦΜ), street
(οδός), cust-city (πόλη-πελάτη).
• Employee (Υπάλληλος), το σύνολο όλων των ατόμων που δουλεύουν στην
τράπεζα, με χαρακτηριστικά empl-name (όνομα-υπαλλήλου) και phone (αριθ.
τηλεφώνου).
• Account (Λογαριασμός), το σύνολο όλων των λογαριασμών της τράπεζας, με
χαρακτηριστικά acc-number (αριθμός λογαριασμού) και balance (υπόλοιπο)
• Transaction (συναλλαγή), το σύνολο όλων των συναλλαγών που γίνονται σε της
τράπεζας, με χαρακτηριστικά trans-number (αριθμός συναλλαγής), date
(ημερομηνία) και amount (ποσό).
Συσχέτιση
CustAcct

Customer
Account

Συσχέτιση
• Σύνδεση μεταξύ οντοτήτων
• Παράδειγμα: Πελάτες σχετίζονται με λογαριασμούς
• Προφανής συσχέτιση: πελάτης έχει λογαριασμό
• Μπορεί να είναι και κάτι άλλο: πελάτης συνδέει την κάρτα με
λογαριασμό
• Άλλο παράδειγμα: Υπάλληλοι σχετίζονται με προϊστάμενο
• Προφανής συσχέτιση: υπάλληλος έχει προϊστάμενο
• Ερώτημα: ποιες οντότητες σχετίζονται??
Υπάλληλοι – Προϊστάμενοι

Είναι δύο οι οντότητες?


• Τα δύο σύνολα είναι ίδια
• Όλα (ή σχεδόν) τα μέλη του αριστερού συνόλου σχετίζονται με
μερικά από τα μέλη του δεξιού συνόλου

• Αν «διπλώσουμε» το σχήμα στη μέση….


Υπάλληλοι – Προϊστάμενοι

Σχέση ρόλων
• Το σύνολο απεικονίζεται στον εαυτό του
• Υπάρχει κάποιος ρόλος που συνδέει δύο μέλη του συνόλου μεταξύ
τους
• Πάντα η σχέση είναι 1-Ν

Προΐσταται

• Υπάλληλοι
υφιστάμενος
Ασθενής οντότητα
• Transaction (συναλλαγή), το σύνολο όλων των συναλλαγών που
γίνονται σε της τράπεζας, με χαρακτηριστικά trans-number (αριθμός
συναλλαγής), date (ημερομηνία) και amount (ποσό).

• Η συναλλαγή καταγράφεται σε όσους λογαριασμούς εμπλέκονται


• Ο αριθμός μπορεί να είναι ίδιος σε διαφορετικούς λογαριασμούς

Ασθενής οντότητα
trans-number date amount
12-345-ΑΒ-253467 12/3/2021 100.00
17-345-ΑΕ-527167 14/3/2021 120.00
12-345-ΑΒ-253467 12/3/2021 100.00
Ασθενής - ισχυρή
• Απαραίτητο: σύνδεση με ισχυρή οντότητα
• Μοναδική σύνδεση με το διάγραμμα E-R
• Σχέση ένα-προς-πολλά

Ασθενής οντότητα - παράδειγμα


Βάση δεδομένων μιας εταιρείας
• Υπάλληλοι: θέση, ΑΦΜ, τέκνα, μισθός, τμήμα
• Τμήμα: κωδικός, όνομα, υπάλληλοι
• Θέσεις: όνομα, βασικός μισθός
• Τέκνα: βαπτιστικό όνομα, γονέας, ηλικία

• Εδώ μας ενδιαφέρει μόνο η οντότητα των τέκνων


Ασθενής οντότητα - παράδειγμα
Τι χαρακτηριστικά έχουν τα τέκνα?
• Όνομα και ηλικία σίγουρα
• Ο γονέας?
• Ανήκει σε άλλη οντότητα: είναι υπάλληλος

• Όνομα και ηλικία μπορεί να είναι ίδια σε πολλά παιδιά: Γιώργος, 3


ετών
• Συνεπώς δεν μπορώ να βρώ κάτι που να ξεχωρίζει σίγουρα τις
οντότητες → ασθενής οντότητα

Ασθενής οντότητα - παράδειγμα


• Λύση: σύνδεση με ισχυρή οντότητα που θα «δώσει ζωή»
• Μόνη επιλογή ο γονέας

Τέκνο Γονέας

• Αν ξέρω τον γονέα, το τέκνο είναι μοναδικό: δεν μπορεί να υπάρχει


παιδί του ίδιου γονέα με ίδια ηλικία και ίδιο όνομα
Mετατροπή σε πίνακες

Μετατροπή σε πίνακες-οντότητα
• Οντότητα: κάθε χαρακτηριστικό → μία στήλη
• Κάθε στήλη παίρνει όνομα
• Το όνομα έχει κανόνες
• Δεν είναι κάτι αφηρημένο
• Ακολουθεί η υλοποίηση σε υπολογιστή, με λογισμικό κτλ
• Κλειδί
• στοιχείο με μοναδικές τιμές
• Όχι κενές τιμές
Συσχέτιση

Μετατροπή σε πίνακες: συσχέτιση


• Χαρακτηριστικά??

• Η σχέση εξ αρχής «περιλαμβάνει» τις οντότητες


• Η «γραμμή» που συνδέει τις «κουκίδες»

• Συνεπώς:
• Κάθε κλειδί οντότητας → αντίστοιχες στήλες (ανάλογα με το πόσα
χαρακτηριστικά περιέχει το κάθε κλειδί)
• Χαρακτηριστικά συσχέτισης: κάθε χαρακτηριστικό → στήλη
• Κλειδί?
Κλειδί συσχέτισης

• Απάντηση: εξαρτάται ☺

• Τι είναι μοναδικό σε μια συσχέτιση?

Μετατροπή σε πίνακες: ασθενής οντότητα


• Πρόβλημα: δεν υπάρχει κλειδί
• Υπενθύμιση: ασθενής οντότητα παίρνει ζωή από ισχυρή οντότητα
• Σχέση 1 προς πολλά

γονέας σχέση τέκνο

ΑΦΜ
Ονομα Κωδικός ηλικία
όνομα
Ασθενής οντότητα
• Χαρακτηριστικά → στήλες (όπως και οι ισχυρές)
• Ζωή?

+ κλειδί ισχυρής οντότητας

• Τέκνο: όνομα, ηλικία (ή έτος γέννησης) + κωδικός (ή ΑΦΜ) γονέα

Ασθενής οντότητα
• Κλειδί της ασθενούς οντότητας?

ΑΦΜ + όνομα τέκνου

• Και η συσχέτιση μεταξύ τους τι πίνακα δίνει?


• «Κανονικά»:
• Κλειδιά οντοτήτων
• Άλλα χαρακτηριστικά συσχέτισης
• Αρα: (ΑΦΜ, όνομα τέκνου) + ΑΦΜ → (ΑΦΜ, όνομα τέκνου)
Ασθενής οντότητα
• Παράσταση συσχέτισης: σχέση (ΑΦΜ, όνομα τέκνου)
• Ποιο είναι το πρόβλημα?

• Γονέας (ΑΦΜ, όνομα, κωδικός) →


σχέση (ΑΦΜ, όνομα τέκνου) →
Τέκνο (ΑΦΜ, όνομα τέκνου, ηλικία)

Ο πίνακας της ασθενούς οντότητας είναι ίδιος με τη συσχέτιση ==>


ΔΕΝ χρειάζεται πίνακας για τη συσχέτιση

Κλειδί συσχέτισης
• 1-1: κάθε κλειδί μοναδικό

• Μπορεί να είναι το κάθε


ένα μόνο του
Κλειδί συσχέτισης
• 1-Ν: η πλευρά του «1» επαναλαμβάνεται

• Μπορεί να είναι κλειδί μόνο


η πλευρά του «Ν»

Κλειδί συσχέτισης
• M-Ν: και οι δύο πλευρές επαναλαμβάνονται

• Κλειδί μπορεί να είναι μόνο


ο συνδυασμός
Κλειδί συσχέτισης - χαρακτηριστικά
Τι γίνεται όταν υπάρχουν και χαρακτηριστικά?

• Κάτοχος λογαριασμού (AFM, acc-number, startdate)


• Μ-Ν
• Έχουμε καταχωρίσει και το πότε μπήκε ο συγκεκριμένος
κάτοχος

Κλειδί συσχέτισης - χαρακτηριστικά

«Λογικό» κλειδί: (AFM, acc-number)


• Επηρεάζει η ημερομηνία?
• Πρακτικά «μπορώ να έχω ίδιο ΑΦΜ στον ίδιο λογαριασμό,
με διαφορετικές ημερομηνίες?»

• Απάντηση: ΌΧΙ → το κλειδί παραμένει ίδιο


Κλειδί συσχέτισης - χαρακτηριστικά
Εξέταση ασθενούς (όνομα εξέτασης, ΑΜΚΑ ασθενούς,
ημερομηνία, αποτέλεσμα)
• Μ-Ν
• Δεν μας φτάνουν τα κλειδιά των οντοτήτων (ο ίδιος ασθενής
μπορεί να ξανακάνει την ίδια εξέταση)
• Ποιος ξεχωρίζει τις διαφορετικές «ίδιες» εξετάσεις?
• Απάντηση: η ημερομηνία (κι αυτό παίζεται ☺ )
• Αρα κλειδί: (όνομα εξέτασης, ΑΜΚΑ, ημερομηνία)

Σύνοψη

• Κλειδί: μοναδικές τιμές, δεν μπορεί να είναι κενό


• Οντότητες: κάτι μοναδικό, προσδιοριστικό
• Ασθενής οντότητα: κλειδί ισχυρής + κάτι διευκρινιστικό
• Συσχέτιση
✓1-1: κάποιο από τα δύο
✓1-Ν: η πλευρά του Ν (προσοχή, όχι η πλευρά του «1»)
✓Μ-Ν: ο συνδυασμός
✓Αν επιπλέον χαρακτηριστικά: το ξανακοιτάμε συγκεκριμένα
Σχεσιακό μοντέλο –
σχεσιακή άλγεβρα

Σχεσιακό μοντέλο
• Σχεσιακή Βάση Δεδομένων: συλλογή πινάκων
• Κάθε γραμμή: πλειάδα (tuple)
• Ενιαία μονάδα
• Συνδυασμός τιμών από σύνολα τιμών

• Σχήμα: αντίστοιχο του τύπου στις γλώσσες προγραμματισμού


deposit-scheme = (br-name, acc-number, cust-name, balance)
• Λίστα χαρακτηριστικών, με αντίστοιχα πεδία τιμών
(br-name: string, acc-number: integer, cust-name: string, balance: integer)
Θα ασχοληθούμε με τους τύπους δεδομένων αργότερα
Παράδειγμα αναφοράς
• Branch-scheme = (br-name, assets, br-city)
• Customer-scheme = (cust-name, street, cust-city)
• Deposit-scheme = (br-name, acc-number, cust-name, balance)
• Borrow-scheme = (br-name, loan-number, cust-name, amount)

Παράδειγμα αναφοράς
• Branch-scheme = (br-name, assets, br-city)
• Customer-scheme = (cust-name, street, cust-city)
• Deposit-scheme = (br-name, acc-number, cust-name, balance)
• Borrow-scheme = (br-name, loan-number, cust-name, amount)
Συσχέτιση

Συσχέτιση
• Άλλο παράδειγμα:
Customer-scheme = (cust-name, street, cust-city)
Μερικές παρατηρήσεις
• Cust-name: εμφανίζεται και στους δύο πίνακες
• Δεν είναι τυχαίο
• Δείχνει τη πραγματική συνάφεια δεδομένων σε διαφορετικούς πίνακες
• Χρησιμοποιείται για τη σύνδεση μεταξύ πινάκων

• Οι δύο σχέσεις μπορεί να γίνουν μία


Account-info-scheme = (branch-name, acc-number, balance, cust-name,
street, cust-city)
• Πελάτης με πολλούς λογαριασμούς → καταχώρηση της διεύθυνσης πολλές φορές
(πλεονασμός)
• Αν δεν υπάρχει διεύθυνση → κενές τιμές (null values)

Γλώσσα Ερωτημάτων (query language)


• Γλώσσα ερωτημάτων: εργαλείο αναζήτησης πληροφορίας
• Λογικές σχέσεις και πράξεις
• Εμπορικές γλώσσες: SQL

Σχεσιακή άλγεβρα
• Σύνολο πράξεων με λογική αλληλουχία
• Αφηρημένη (abstract)
Βασικές λειτουργίες
Επιλογή (select)
• Επιλογή πλειάδων με συγκεκριμένη συνθήκη
• Συμβολίζεται με το γράμμα σ

γονέας σχέση τέκνο

ΑΦΜ
Ονομα Κωδικός ηλικία
όνομα

Βασικές λειτουργίες
Επιλογή (select)
• Επιλογή πλειάδων με συγκεκριμένη συνθήκη
• Συμβολίζεται με το γράμμα σ
σ br-name = ‘Ακαδημία’ (borrow)

• Μετάφραση: επίλεξε από τον πίνακα borrow τις γραμμές (πλειάδες)


που έχουν την τιμή «Ακαδημία» στη στήλη Br-name
• Τι είναι το αποτέλεσμα? (σκεφθείτε)
Βασικές λειτουργίες
Απάντηση: πίνακας!
• Όλες οι πράξεις στη σχεσιακή άλγεβρα γίνονται σε πίνακες και
δίνουν αποτέλεσμα πίνακα

• Πίνακας με ίδιο πλήθος στηλών και μικρότερο (ή ίσο) πλήθος


πλειάδων

• Μπορεί να είναι και «ίσο»: κάποια συνθήκη μπορεί να


ικανοποιείται από όλες τις γραμμές του πίνακα
σ loan-number > 10 (borrow) = borrow

Παράδειγμα
Αποτέλεσμα

σ br-name = ‘Ακαδημία’ (borrow)

Παραδείγματα
• Δάνεια με ποσό πάνω από 2000 ευρω
σ amount > 2000 (borrow)

• Πελάτες από Αθήνα


σ cust-city =“Αθήνα”(customer)
• Καταστήματα με περιουσία πάνω από 100000
σ assets > 100000(Branch)
Παρατηρήσεις
• Λογικές συγκρίσεις με λογικούς τελεστές
<, >, =, ≤, ≥, ≠
• Σύγκριση πεδίου με τιμή
• Συνθήκες μπορούν να συνδυάζονται με λογικούς τελεστές
AND, OR, NOT, XOR, NAND, NOR
• Μπορούμε να συγκρίνουμε πεδία μεταξύ τους

Βασικές λειτουργίες
Προβολή (project)
• Επιλογή χαρακτηριστικών (στηλών) από πίνακα
• Συμβολίζεται με το γράμμα Π
Π br-name, br-city (branch)

• Μετάφραση: επίλεξε από τον πίνακα branch τις στήλες Br-name, Br-
city
• Τι είναι το αποτέλεσμα? (σκεφθείτε)
Βασικές λειτουργίες
Απάντηση: πίνακας!
• Έχει το πλήθος των στηλών που επιλέξαμε
• Έχει το ίδιο πλήθος γραμμών με τον αρχικό πίνακα
• Δεν «διώχνουμε» πληροφορία
• «Προβάλλουμε» αυτά που μας ενδιαφέρουν

Παραδείγματα

• Ονόματα πελατών και το κατάστημα στο οποίο έχουν κάποιο δάνειο


Π br-name, cust-name (borrow)
• Ονόματα και πόλεις καταστημάτων
Π br-name, br-city (branch)
• Αριθμοί και υπόλοιπα λογαριασμών
Π acc-no, balance (deposit)
Παραδείγματα

• Δεν είναι απαραίτητο να έχουμε έναν από τους αποθηκευμένους


πίνακες μας
• Τί είναι το σ loan-number > 1400 (borrow) ?
• Απάντηση: πίνακας (όχι αποθηκευμένος όμως)
• Οι στήλες του παραμένουν ίδιες:
(br-name, loan-number, cust-name, amount)
• Τι κάνω αν θέλω μόνο τους αριθμούς και τα ποσά των δανείων?

Παραδείγματα

• Κάνω προβολή στον πίνακα που έχω «υπολογίσει»

Π loan-number, amount (σ loan-number > 1400 (borrow))

• Έτσι μπορώ να συνδυάζω Π και σ


• Σχεδόν όλες οι πράξεις που θέλω να κάνω σε μια φυσιολογική βάση
γίνονται με αυτόν τον συνδυασμό
Παραδείγματα συνδυασμών

• Ονόματα και πόλεις πελατών από την Άρτα


Π cust-name, cust-city (σ cust-city = ‘Αρτα’(customer))
• Κατάστημα και ποσό για τα δάνεια του καταστήματος Κέντρο
Π br-name, amount (σbr-name = ‘Κέντρο’(borrow))
• Αριθμοί δανείων με ποσό πάνω από 2000 ευρώ
Π loan-number (σ amount > 2000 (borrow))
Ερώτημα: Είναι πρόβλημα ότι δεν κρατάω στην προβολή τη στήλη που
είναι στη συνθήκη?

Παραδείγματα συνδυασμών
• Απάντηση : όχι!
• Πρώτα υπολογίζω τον πίνακα και μετά κρατάω αυτά που θέλω
• Στο παράδειγμα: δεν ξέρω τα ποσά των δανείων, ξέρω όμως ότι
είναι σίγουρα πάνω από 2000 ευρώ.
Μερικές λεπτομέρειες
• Οι συνθήκες μπορούν να συνδέονται με AND, OR, XOR, NOT και
άλλους λογικούς τελεστές
• Η τελική μας συνθήκη είναι μία, μπορεί όμως να αποτελεί σύνθεση
πολλών άλλων
• Στις συνθήκες μπορώ να έχω και διάφορες «συντομεύσεις»:
• ΙΝ: αντίστοιχο του ϵ
Acc-number IN (1000, 2100, 3535)
Ισοδύναμο με Acc-no = 1000 OR acc-no=2100 OR acc-no = 3535
• BETWEEN - AND: ισοδύναμο με δύο συνθήκες που ορίζουν μια περιοχή
Acc-number BETWEEN 1000 AND 2000
Ισοδύναμο με Acc-number >1000 AND Acc-number <2000
• LIKE: αναζήτηση για σειρές χαρακτήρων που μοιάζουν με κάτι

Η χρήση του LIKE


• Δεν μπορούμε με το = να βρούμε λέξεις που μοιάζουν με κάτι
• Πχ. Στην Άρτα ονομάζουμε τα καταστήματα μας ‘Άρτα1’ και ‘Άρτα2’
• Δεν μπορούμε να τα βρούμε με br-name = ‘Άρτα’
• Ούτε το ένα όνομα ούτε το άλλο έχουν ίδια ακριβώς τιμή με αυτό που
αναζητάμε, παρά το ότι διαφέρουν μόνο στον ένα επιπλέον χαρακτήρα
• Πρέπει να μπορούμε να αναζητήσουμε τμήματα λέξεων

Η απάντηση: ο τελεστής LIKE


Η χρήση του LIKE
Cust-name LIKE ‘A%’: αναζήτηση ονομάτων που αρχίζουν από Α
Cust-name LIKE ‘%Σ’: αναζήτηση ονομάτων που τελειώνουν σε Σ
Cust-name LIKE ‘%AΒ%’: αναζήτηση ονομάτων που έχουν κάπου μέσα
στη σειρά το ‘ΑΒ’
Cust-name LIKE ‘A_ _’: αναζήτηση ονομάτων που αρχίζουν από Α και
μετά ακολουθούν δύο (αυστηρά) χαρακτήρες
Cust-name LIKE ‘%A_ _ _’: αναζήτηση ονομάτων που έχουν κάπου το Α
και μετά ακολουθούν τρεις (αυστηρά) χαρακτήρες μέχρι το τέλος

Διάταξη
• Σημαντικό στοιχείο στις βάσεις δεδομένων
• Σειρά με βάση μια αύξουσα ακολουθία
• Ό,τι μπορεί να μπει σε μια αύξουσα ακολουθία μπορεί και να
μπει σε διάταξη
• Αριθμοί: σύμφωνα με τη γνωστή διάταξη των φυσικών αριθμών
• Ημερομηνίες: η πιο πρόσφατη ημερομηνία θεωρείται μεγαλύτερη από
μια παλιότερη
• Σειρές χαρακτήρων: αλφαβητικά, όπως στο λεξικό
Διάταξη
• Προσοχή: οι λέξεις μπορούν και αυτές να συγκριθούν
• Παράδειγμα: τι σημαίνει Cust-name > ‘Βερ’ ?
• Απάντηση: όλες οι λέξεις / φράσεις που θα ήταν μετά τη λέξη
‘Βερ’ στο λεξικό
• Βεργα, βεστιάριο, γράμμα, δρόμος
Αλλά όχι
• βελάκι, βαρος, αλγεβρα

Διάταξη
• Μπορούμε να συγκρίνουμε με ανισότητες και λέξεις μεταξύ τους
• «Μεγαλύτερη» είναι η λέξη που βρίσκεται παρακάτω στο λεξικό
• Βγενόπουλος > Βα (το α είναι πριν το γ)
• Παύλου < Πε (το ε είναι μετά το α)
• Γ < Γεωργίου (το Γ εμφανίζεται πριν από οποιαδήποτε λέξη από Γ)
• Θα μπορούσαμε να βρούμε και μια ομάδα λέξεων με ανισότητες
• Πχ τα ονόματα καταστημάτων από Δ μπορούν να βρεθούν
• Br-name >= ‘Δ’ AND Br-name < ‘E’
• Φυσικά σπανίως θα κάνουμε κάτι τέτοιο, όταν έχουμε εργαλεία που
κάνουν την ίδια δουλειά με πιο φυσικό τρόπο
Πράξεις συνόλων

Πίνακες ΒΔ: Σύνολα


• Όλοι οι πίνακες των Βάσεων Δεδομένων είναι κι αυτοί ΣΥΝΟΛΑ
• Ισχύουν όλα όσα ξέρουμε για τα σύνολα
• Τομή – Ένωση - Διαφορά

• Προσοχή: στοιχεία των συνόλων αυτών είναι ολόκληρες οι γραμμές


• -όχι τα επιμέρους χαρακτηριστικά

• Μπορούμε να χειριστούμε τους πίνακες ως σύνολα


• Πολύ βοηθητικό εργαλείο για τη συσχέτιση όμοιων δεδομένων
Παράδειγμα
• Ονόματα πελατών που έχουν ταυτόχρονα λογαριασμό και δάνειο
• Θυμηθείτε την απάντηση μας:
Π[Link]-name(Deposit >< cust-name borrow)

• Τι ζητάμε?

Ονόματα πελατών που είναι και στον πίνακα Deposit και στον πίνακα
Borrow

• Αυτός είναι ο ορισμός της τομής ( ∩ ) δύο συνόλων

Παράδειγμα
• Συνεπώς, απάντηση:
Π[Link]-name (Deposit ∩ borrow)

• Είναι έτσι ? (σκεφτείτε)


Παραδείγματα
• Γραμμή του Deposit: (123456, Πέτρου, Κέντρο, 102.35)
• Γραμμή του Borrow: (42535, Πέτρου, Ομόνοια, 205.39)

• Μια πράξη τομής δεν θα τσεκάρει μόνο το κοινό στοιχείο (Πέτρου)


• Αντίθετα, θα προσπαθήσει να ελέγξει ολόκληρη τη γραμμή
• Οι δύο γραμμές δεν είναι ίδιες, άρα η τομή δεν θα βγάλει κάτι

Παραδείγματα
• Λύση: -- πρώτα απομονώνω τα ονόματα
-- μετά κάνω την τομή

Πcust-name, br-name (Deposit) ∩ Πcust-name , br-name(borrow)


• Η τομή των «πινάκων»

∩ =
Προϋποθέσεις
• Πρέπει να μπορώ να συγκρίνω γραμμές
• Για να συμβεί αυτό, πρέπει οι γραμμές να είναι συμβατές:

• Ίδιο πλήθος χαρακτηριστικών


Δεν μπορώ να συγκρίνω μια γραμμή 4 στηλών με μια γραμμή 5 στηλών
• Ίδιοι τύποι δεδομένων αντίστοιχα
Δεν μπορώ να συγκρίνω μια λέξη (τύπος varchar (20) ) με μια ημερομηνία
(τύπος date)
• Συνήθως η πράξη γίνεται μεταξύ πινάκων που σχηματίζω για αυτό το
σκοπό, άρα πληρούνται εξ ορισμού οι προϋποθέσεις

Προϋποθέσεις
• Συνήθως η πράξη γίνεται μεταξύ πινάκων που σχηματίζω για αυτό το
σκοπό, άρα πληρούνται εξ ορισμού οι προϋποθέσεις

• Ας το ξαναδούμε:
Μπορώ να συγκρίνω deposit και borrow ?
• Deposit(br-name, acc-number, cust-name, balance)
• Borrow (br-name, loan-number, cust-name, amount)

Ναι!
Αλλά συνήθως δεν σημαίνει τίποτα
Πράξεις
• Ένωση Α U Β : σχηματισμός ενός πίνακα, με τις γραμμές και των δύο πινάκων
• Ισοδύναμο με το Α OR Β

• Τομή Α ∩ Β : σχηματισμός ενός πίνακα, μόνο με τις κοινές γραμμές των δύο
πινάκων
• Ισοδύναμο με το Α AND Β

• Διαφορά Α – Β : σχηματισμός ενός πίνακα, με τις γραμμές του πρώτου χωρίς τις
γραμμές που είναι και στον δεύτερο
• Ισοδύναμο με το Α AND (ΝΟΤ Β)
• Προσοχή: η διαφορά δεν είναι αντιμεταθετική Α- Β ≠ Β-Α

Παραδείγματα
• Πελάτες με καταθέσεις των καταστημάτων Κέντρο και Ομόνοια
• Ορθή διατύπωση: «Κέντρο ή Ομόνοια»
Πcust-name (σ br-name=‘Κέντρο’(Deposit)) U Πcust-name (σ br-name=‘Ομόνοια’(Deposit))

• Πελάτες με καταθέσεις και στο Κέντρο και στην Ομόνοια


• Ορθή διατύπωση: «Κέντρο και Ομόνοια ταυτόχρονα»
Πcust-name (σ br-name=‘Κέντρο’(Deposit)) ∩ Πcust-name (σ br-name=‘Ομόνοια’(Deposit))

• Πελάτες με καταθέσεις που δεν έχουν δάνειο


Πcust-name (Deposit) - Πcust-name (borrow)
• Προσοχή: αυτό δεν μπορούσα να το κάνω με τη φυσική σύνδεση!
Παραδείγματα
S (S#, SNAME, STATUS, CITY)
P(P#, PNAME, COLOR, WEIGHT, CITY)
J (J#, JNAME, CITY)
SPJ(S#, P#, J#,POSOT)
• S: πίνακας προμηθευτών
• P: πίνακας υλικών
• J: πίνακας έργων
• SPJ: πίνακας παραγγελιών

Παραδείγματα
• Όλες οι λεπτομέρειες των έργων
J
• Τα στοιχεία των έργων στην Αθήνα
σ city = ‘Αθήνα’ (J)
• Κωδ. Προμηθευτή που προμηθεύει το έργο J1
Π S# (σ J# = ‘J1’(SPJ) )
• Παραγγελίες με ποσότητες από 300 έως 700
σ 300 <posot < 700 (SPJ)
• Ζευγάρια χρωμάτων και πόλεων υλικών
Π color, city (P)
• Βρείτε τριάδες κωδικών προμηθευτή, υλικού και έργου που είναι στην ίδια πόλη
σ [Link] = [Link] AND [Link] = [Link] (S X P X J)
Παραδείγματα
• Βρείτε τριάδες κωδικών προμηθευτή, υλικού και έργου που δεν είναι όλοι στην
ίδια πόλη
σ [Link] ≠ [Link] OR [Link] ≠ [Link] OR [Link] ≠ [Link](S X P X J)
• Βρείτε τριάδες κωδικών προμηθευτή, υλικού και έργου που είναι όλοι σε
διαφορετική πόλη
σ [Link] ≠ [Link] AND [Link] ≠ [Link] AND [Link] ≠ [Link](S X P X J)
• Κωδικοί υλικών που δίνει κάποιος προμηθευτής από Αθήνα
Π P#(σ city = ‘Αθήνα’ (SPJ >< S))
• Κωδικοί υλικών που δίνει κάποιος προμηθευτής από Αθήνα σε έργα στην Αθήνα
Π P#(σ [Link] = ‘Αθήνα’ AND [Link] = ‘Αθήνα’ (J >< SPJ >< S))
• Ζεύγη πόλεων ώστε ένας προμηθευτής από την πρώτη πόλη προμηθεύει κάποιο
έργο στη δεύτερη πόλη
Θέλουμε να φέρουμε στην ίδια γραμμή την πόλη του έργου και την πόλη του προμηθευτή
Π [Link], [Link] (J >< SPJ >< S)

Παραδείγματα
• Κωδικοί υλικών που δίνει κάποιος προμηθευτής σε έργα στην πόλη
του
ΠP# (σ [Link] = [Link] (S >< SPJ >< J))
• Κωδικοί έργων που προμηθεύονται υλικά από τουλάχιστον έναν
προμηθευτή από άλλη πόλη
ΠJ# (σ [Link] ≠ [Link] (S >< SPJ >< J))
• Ζεύγη υλικών που κάποιος προμηθευτής προμηθεύει και τα δύο
(Σκεφτείτε)
Παραδείγματα
• Ζεύγη υλικών που κάποιος προμηθευτής προμηθεύει και τα δύο
Θυμηθείτε: κάθε πράξη πρέπει να ψάχνει στην ίδια γραμμή
• Ζεύγη υλικών που κάποιος προμηθευτής προμηθεύει και τα δύο

Παραδείγματα
• Ονόματα έργων για έργα που προμηθεύονται υλικά από τον
προμηθευτή S1
Π[Link] (σ S# = ‘S1’(SPJ >< J))
Αν και δεν χρειάζεται το όνομα του πίνακα, δεν δημιουργεί πρόβλημα

Εναλλακτικά
ΠJname (σ J# IN (σ S# = ‘S1’ (SPJ))(J))
Δεν χρειάζεται η φυσική σύνδεση, μπορούμε να αποσυνδέσουμε τους δύο πίνακες
• Χρώματα υλικών που δίνει ο S1
Πcolor (σ S# = ‘S1’ (SPJ >< P))
Παραδείγματα
• Κωδικοί προμηθευτή για προμηθευτές που δίνουν τουλάχιστον ένα υλικό που
δίνεται από ένα τουλάχιστον προμηθευτή που δίνει κάποιο κόκκινο υλικό

• Φωλιασμένα ερωτήματα
• Λύση: ξεκινάμε ανάποδα και πηγαίνουμε προς τα πίσω

• Προμηθευτές που δίνουν ένα κόκκινο υλικό


ΠS# (σ color = ‘κοκκινο’(P >< SPJ )) = Α

• Υλικά που δίνουν αυτοί οι προμηθευτές


ΠP# (σ S# IN A (SPJ )) = B
• Προμηθευτές που δίνουν αυτά τα υλικά
ΠS# (σ P# IN B (SPJ ))

Παραδείγματα
• Κωδικοί προμηθευτή με στάτους μικρότερο από αυτό του S1
ΠS# (σstatus < x (S) )
Χρειαζόμαστε μια τιμή που δεν ξέρουμε
• Πώς τη βρίσκουμε? Χ = Πstatus (σs# = ‘S1’ (S) )

• Κωδικοί έργων που τα προμηθεύει αποκλειστικά ο S1


(σκεφτείτε)
Παραδείγματα
• Κωδικοί έργων που τα προμηθεύει αποκλειστικά ο S1
• Τι ζητάω? → Έργα που παίρνουν μόνο από τον S1
• Πώς το βρίσκω? → Αν κάποιος άλλος δίνει σε κάποιο έργο, διώχνω αυτό το έργο

• «Διώχνω» σημαίνει διαφορά


• Ποια είναι αυτά που θέλω να διώξω?

ΠJ# (σs# ≠ ‘S1’ (SPJ) )


• Πώς βρίσκω όλα τα έργα?
ΠJ# (J)

• Τελικά αφαίρεση: ΠJ# (J) -ΠJ# (σs# ≠ ‘S1’ (SPJ) )

SQL: το μεγάλο όπλο των ΒΔ


SQL: μια ειδική «γλώσσα»
• Σχεσιακή άλγεβρα: πλήρης συμβολισμός για όλες τις ενέργειες
• Αφηρημένος όμως
• Χρειάζεται μια formal γλώσσα για την επεξεργασία σε υπολογιστή
SQL
Structured Query Language

• Tο εμπορικό standard
• Όλοι το ακολουθούν

SQL: μια μακρά ιστορία


• αρχική έκδοση: San Jose Research Laboratory της IBM
• Πρώτη εκδοχή: Sequel (αρχές δεκαετίας 70)
• Τεράστια εξέλιξη – νέο όνομα SQL (Structured Query Language,
Γλώσσα Δομημένων Ερωτημάτων)
• 1986: αποδεκτό σαν standard από το American National Standards
Institute (ANSI)
• Όλα τα εμπορικά προϊόντα την υποστηρίζουν
Τι θέλουμε εδώ
• Βασικές αρχές
• Κανόνες και δομή των εντολών
• ΔΕΝ ΧΡΕΙΑΖΕΤΑΙ απομνημόνευση – υπάρχουν τα
manuals ☺
• Τι δουλεύει – τι είναι λάθος

Βασικοί κανόνες (1/2)


• Συγκεκριμένη δομή – η εντολή με λάθη δεν τρέχει
• Λέξεις reserved: δεν μπορούν να χρησιμοποιηθούν για
ονόματα πινάκων κτλ (SELECT, INSERT, FROM, …)

• Λάθη: πάντα υπάρχει εξήγηση – όχι πάντα η «σωστή»


• Θέλουμε να μάθουμε να τα «διαβάζουμε»

• Δεν έχουν σημασία κεφαλαία και μικρά γράμματα


• Συνήθης κώδικας: με κεφαλαία τα τμήματα των εντολών, με
μικρά τα υπόλοιπα
Βασικοί κανόνες (2/2)
• Υπάρχουν διάφορα μικρά «τουβλάκια»
• Χρησιμοποιούνται όπου χρειάζεται η δουλειά που κάνουν

• WHERE <συνθήκη> : όπου ισχύει η συνθήκη κάνε …


• Χρησιμοποιείται στην SELECT, την UPDATE, την DELETE

• H εντολή μπορεί να γραφεί σε μια γραμμή ή σε πολλά μικρά


κομμάτια
• Δεν έχει καμιά διαφορά, μέχρι να «πούμε» ότι η εντολή
τελείωσε και πρέπει να τρέξει (συνήθως με ; )

Εντολή Select
• Δομή της εντολής:
Select <λίστα εκφράσεων>
From <λίστα πινάκων>
[Where <συνθήκη>]
[Order By <λίστα πεδίων>]
[Group By <λίστα πεδίων>
[Having <συνθήκη>]]
• Απαραίτητα μόνο τα πρώτα
• Η σειρά είναι συγκεκριμένη
Εντολή Select
• Λειτουργία:

➢ FROM: πάρε αυτούς τους πίνακες (θυμηθείτε: πρώτα η παρένθεση)


➢ WHERE: κράτησε μόνο αυτές τις γραμμές
➢ SELECT: Επίλεξε αυτές τις εκφράσεις

• Δεν αλλάζει κάτι στον αποθηκευμένο πίνακα


• Σχηματίζεται ένας νέος πίνακας
• «Εξαφανίζεται» μετά το κλείσιμο
• Μπορεί όμως να ξανασχηματιστεί τρέχοντας την εντολή
• Εκφράσεις: χαρακτηριστικά, συναρτήσεις, απλές τιμές
• Όλα τα χαρακτηριστικά: *

Εντολή Select: συντομεύσεις


• ΙΝ: «ανήκει» σε ένα σύνολο με συγκεκριμένες τιμές
• Acc-no ΙΝ (1, 4, 8)
• Μία από τις συγκεκριμένες τιμές
• Ισοδύναμο με Acc-no = 1 OR Acc-no = 4 OR …

• BETWEEN: τιμές σε ένα διάστημα


• Balance BETWEEN 100 AND 200
• LIKE: ομοιότητα με μια σειρά χαρακτήρων (% για πολλούς, _ για ένα)
• Cust-name LIKE ‘Πέτ%’
• Cust-name LIKE ‘Πέτρ_ _’
• Cust-name LIKE ‘%τρ_ _’
Εντολή Select: τεχνικές λεπτομέρειες
• Σχεδόν πάντα μονά εισαγωγικά- πάντα πρέπει να
κλείνουν
• Λογικοί τελεστές AND, OR, NOR, NOT, NAND, XOR
• Λίστες πάντα σε παρένθεση
• Διαχωρισμός λιστών με κόμματα (,)
• Παρενθέσεις: βοηθούν – δεν είναι απαραίτητες – δεν
κάνουν ζημιά

Εντολή Select: παραδείγματα


• Ονόματα καταστημάτων της Αθήνας
SELECT br-name
FROM branch
WHERE br-city = ‘Αθήνα’
• Υπόλοιπα λογαριασμών και ονόματα των πελατών Παύλου
και Πέτρου
SELECT balance, cust-name
FROM deposit
WHERE (cust-name = ‘Παύλου’ OR cust-name = ‘Πέτρου’ )
Εντολή Select: παραδείγματα
• Αριθμοί δανείων και τόκοι για κάθε δάνειο με ποσό μεταξύ
10000 και 20000
SELECT loan-no, 0.08*amount
FROM borrow
WHERE amount>10000 AND amount < 20000
• Όλα τα στοιχεία των πελατών από την Αθήνα, την Λάρισα και
την Πάτρα
SELECT *
FROM Customer
WHERE br-city IN (‘Αθήνα’, ‘Λάρισα’, ‘Πάτρα’)

Εντολή Select: βγάζει πίνακα


• Η select δεν αλλάζει κάτι στα αποθηκευμένα
δεδομένα
Αλλά
• Δημιουργεί έναν καινούριο πίνακα
• Διαθέσιμος όσο δουλεύουμε με αυτόν
• Μπορεί να χρησιμοποιηθεί σε άλλη select
Παραδείγματα
• Είδαμε «Όλα τα στοιχεία των πελατών από την Αθήνα, την Λάρισα και την
Πάτρα»
• «Μικρή» αλλαγή: δεν ξέρουμε τις πόλεις (αλλά μπορούμε να τις βρούμε)

Όλα τα στοιχεία των πελατών από πόλεις που έχουν κατάστημα «Κέντρο»

SELECT *
FROM Customer
WHERE cust-city IN ( SELECT br-city FROM branch WHERE br-name =
‘Κέντρο’)

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

• Π.χ. όχι
SELECT * FROM Customer
WHERE cust-city IN ( SELECT br-city, br-name FROM branch WHERE br-name
= ‘Κέντρο’)
• Δεν μπορώ να ψάξω μια μεταβλητή σε ζευγάρια τιμών
Διάταξη
• Νέα σειρά των γραμμών με βάση συγκεκριμένα πεδία
ORDER BY acc-no
• Διατάσσουμε τις γραμμές με αύξουσα σειρά του πεδίου acc-no
• Προφανώς η γραμμή ακολουθεί ολόκληρη ☺

Παραδείγματα
• Μπορώ να υπολογίσω και μία μοναδική τιμή και να την χρησιμοποιήσω σε
συνθήκες

• Κωδικοί προμηθευτή με στάτους μεγαλύτερο από 2 (εύκολο)


SELECT S# FROM S WHERE Status >2

• Τροποποίηση: Κωδικοί προμηθευτή με στάτους μεγαλύτερο από αυτό του S1


(θα χρειαστεί να το υπολογίσουμε)
• Ποιο είναι το στάτους του S1? → SELECT Status FROM S WHERE S# = ‘S1’
Άρα τελικά
SELECT S# FROM S WHERE Status > (SELECT Status FROM S WHERE S#= ‘S1’)
διάταξη
• Περισσότερα πεδία
ORDER BY balance, acc-no
• Πρώτα διάταξη με το πρώτο πεδίο

• Αν υπάρχει ισοπαλία, η σειρά παραμένει όπως ήταν


• Μετά κρίνεται με βάση το δεύτερο

Διάταξη

Προσοχή: μόνο οι γραμμές που είναι ισόπαλες επηρεάζονται


Διάταξη φθίνουσα
ORDER BY balance DESC

• H σειρά αντιστρέφεται
• Η default σειρά είναι η αύξουσα (ASC, αλλά δεν χρειάζεται)
• Κάθε πεδίο μπορεί να έχει διαφορετική σειρά
ORDER BY balance DESC, cust-name ASC, acc-no
• Πρώτα με βάση το υπόλοιπο με φθίνουσα σειρά, αν έχουμε το ίδιο
υπόλοιπο με αλφαβητική σειρά του ονόματος, αν έχουμε και το ίδιο
όνομα με αύξουσα σειρά του αρ. λογαριασμού

Διάφορα παραδείγματα
• Ονόματα πελατών από Αθήνα και Θεσσαλονίκη με αλφαβητική σειρά
SELECT Cust-name FROM Customer
WHERE cust-city = ‘Αθήνα’ OR Cust-city = ‘Θεσσαλονίκη’
ORDER BY Cust-name
• Eναλλακτικά WHERE cust-city ΙΝ ( ‘Αθήνα’ , ‘Θεσσαλονίκη’)

• Μικρή παραλλαγή: με αλφαβητική σειρά, αλλά πρώτα τους Θεσσαλονικείς και


μετά τους Αθηναίους →Πρέπει να διατάξουμε πρώτα ως προς την πόλη, και
μάλιστα με φθίνουσα σειρά!
SELECT Cust-name FROM Customer
WHERE cust-city = ‘Αθήνα’ OR Cust-city = ‘Θεσσαλονίκη’
ORDER BY Cust-city DESC, Cust-name
• Προσοχή: δεν χρειάζεται τα πεδία του ORDER BY να εμφανίζονται και στο SELECT
• To ίδιο ισχύει και για το WHERE
Διάφορα παραδείγματα
• Αρ. Δανείου και κατάστημα για δάνεια του πελάτη Πέτρου με ποσό
μεταξύ 10000 και 20000 με φθίνουσα σειρά υπολοίπου
SELECT loan-no, br-name FROM Borrow
WHERE cust-name = ‘Πέτρου’ AND (amount BETWEEN 10000 AND
20000)
ORDER BY amount DESC
• Eναλλακτικά (amount <20000 AND amount >10000)
• Εδώ συμβαίνει να μην εμφανίζονται στο SELECT ούτε τα πεδία του
WHERE ούτε το πεδίο του ORDER BY

Παραδείγματα σχεσιακής
άλγεβρας
Παραδείγματα
S (S#, SNAME, STATUS, CITY)
P(P#, PNAME, COLOR, WEIGHT, CITY)
J (J#, JNAME, CITY)
SPJ(S#, P#, J#,POSOT)
• S: πίνακας προμηθευτών
• P: πίνακας υλικών
• J: πίνακας έργων
• SPJ: πίνακας παραγγελιών

Παραδείγματα
• Όλες οι λεπτομέρειες των έργων
J
• Τα στοιχεία των έργων στην Αθήνα
σ city = ‘Αθήνα’ (J)
• Κωδ. Προμηθευτή που προμηθεύει το έργο J1
Π S# (σ J# = ‘J1’(SPJ) )
• Παραγγελίες με ποσότητες από 300 έως 700
σ 300 <posot < 700 (SPJ)
• Ζευγάρια χρωμάτων και πόλεων υλικών
Π color, city (P)
• Βρείτε τριάδες κωδικών προμηθευτή, υλικού και έργου που είναι στην ίδια
πόλη
Π S#, P#, J# (σ [Link] = [Link] AND [Link] = [Link] (S X P X J))
Μπορεί να γίνει και με φυσική σύνδεση ως προς τις πόλεις (ουσιαστικά είναι το ίδιο)
Παραδείγματα
• Βρείτε τριάδες κωδικών προμηθευτή, υλικού και έργου που δεν
είναι όλοι στην ίδια πόλη
Π S#, P#, J# (σ [Link] ≠ [Link] OR [Link] ≠ [Link] OR [Link] ≠ [Link](S X P X J))
Μια από τις τρεις συνθήκες δεν είναι απαραίτητη
• Βρείτε τριάδες κωδικών προμηθευτή, υλικού και έργου που είναι
όλοι σε διαφορετική πόλη
Π S#, P#, J# (σ [Link] ≠ [Link] AND [Link] ≠ [Link] AND [Link] ≠ [Link](S X P X J) )
• Σε αυτά δεν στέκεται η φυσική σύνδεση, γιατί υπάρχει το ≠
• Αυτό δείχνει ότι η φυσική σύνδεση δεν είναι η «τεχνικά ορθή» απάντηση

Παραδείγματα
• Κωδικοί υλικών που δίνει κάποιος προμηθευτής από Αθήνα
Π P#(σ city = ‘Αθήνα’ (SPJ >< S))
• Κωδικοί υλικών που δίνει κάποιος προμηθευτής από Αθήνα σε έργα
στην Αθήνα
Π P#(σ [Link] = ‘Αθήνα’ AND [Link] = ‘Αθήνα’ (J >< SPJ >< S))
• Ζεύγη πόλεων ώστε ένας προμηθευτής από την πρώτη πόλη
προμηθεύει κάποιο έργο στη δεύτερη πόλη
Θέλουμε να φέρουμε στην ίδια γραμμή την πόλη του έργου και την πόλη του προμηθευτή
Π [Link], [Link] (J >< SPJ >< S)
Παραδείγματα
• Κωδικοί υλικών που δίνει κάποιος προμηθευτής σε έργα στην πόλη
του
ΠP# (σ [Link] = [Link] (S >< SPJ >< J))
• Κωδικοί έργων που προμηθεύονται υλικά από τουλάχιστον έναν
προμηθευτή από άλλη πόλη
ΠJ# (σ [Link] ≠ [Link] (S >< SPJ >< J))
• Ζεύγη υλικών που κάποιος προμηθευτής προμηθεύει και τα δύο
(Σκεφτείτε)

Παραδείγματα
• Ζεύγη υλικών που κάποιος προμηθευτής προμηθεύει και τα δύο
Δηλαδή ζεύγη τύπου (Ρ1, Ρ2) που σημαίνει ότι υπάρχει κάποιος προμηθευτής που
προμηθεύει και το Ρ1 και το Ρ2

Θυμηθείτε: κάθε πράξη πρέπει να ψάχνει στην ίδια γραμμή

• Πώς θα φτιάξουμε έναν πίνακα που θα τα φέρει στην ίδια γραμμή?


(σκεφτείτε)
Παραδείγματα
• Οι δύο παραγγελίες έχουν τη μορφή
(S1, P1, J2, 100) ----------- (S1, P2, J3, 250)

• Πρέπει λοιπόν να φέρουμε σε επαφή δύο γραμμές με ίδια τιμή στο


πεδίο S# (σκεφτείτε)

Παραδείγματα
• Απάντηση: φυσική σύνδεση του πίνακα με τον εαυτό του

• Κρατάμε μόνο τις γραμμές με διαφορετικά υλικά


σ SPJ_A.P# ≠ SPJ_B.P# (SPJ_A >< SPJ_B)
• Τέλος κρατάμε μόνο τις δύο στήλες με τα υλικά
Π SPJ_A.P#, SPJ_B.P# (σSPJ_A.P# ≠ SPJ_B.P# (SPJ_A >< SPJ_B))
Προσοχή: οι «πράσινες» γραμμές θα κοπούν από τη συνθήκη, γιατί το υλικό είναι το P1, δηλαδή
στο ζευγάρι που θα σχηματιστεί θα έχω δύο ίδιες τιμές
Παραδείγματα
• Ονόματα έργων για έργα που προμηθεύονται υλικά από τον
προμηθευτή S1
Π[Link] (σ S# = ‘S1’(SPJ >< J))
Αν και δεν χρειάζεται το όνομα του πίνακα, δεν δημιουργεί πρόβλημα

Εναλλακτικά
ΠJname (σ J# ⋲ (Π J# (σ S# = ‘S1’ (SPJ)))(J))
Δεν χρειάζεται η φυσική σύνδεση, μπορούμε να αποσυνδέσουμε τους δύο πίνακες
• Χρώματα υλικών που δίνει ο S1
Πcolor (σ S# = ‘S1’ (SPJ >< P))

Παραδείγματα
• Κωδικοί έργων για έργα που προμηθεύονται κάποιο υλικό από αυτά
που προμηθεύει ο προμηθευτής S1 (όχι απαραίτητα σε αυτό το έργο)
✓Αν ξέραμε ποια είναι αυτά τα υλικά, πχ σε μια λίστα Α, τότε η
απάντηση είναι εύκολη:
ΠJ# (σ P# ⋲ A(SPJ))
✓Πώς θα βρούμε το Α ?
Α = Π P# (σ S# = ‘S1’ (SPJ))
✓ΠΡΟΣΟΧΗ: μιλάμε για διαφορετικές συνθήκες, δεν μπορούμε να τις
συγχωνεύσουμε!
Παραδείγματα
• Λίστα πόλεων που έχουν τουλάχιστον ένα έργο ή ένα υλικό ή έναν
προμηθευτή
Πcity(J) ⋃ Πcity(S) ⋃ Πcity(P)
• Λίστα υλικών που δίνονται είτε από Αθηναίο προμηθευτή είτε σε
έργο της Αθήνας
Ένωση: ΠP#(σ city = ‘Αθήνα’ (SPJ >< S)) ⋃ ΠP#(σ city = ‘Αθήνα’ (SPJ >< J))
• Λίστα υλικών που δίνονται από Αθηναίο προμηθευτή σε έργο της
Αθήνας
Τομή: ΠP#(σ city = ‘Αθήνα’ (SPJ >< S)) ⋂ ΠP#(σ city = ‘Αθήνα’ (SPJ >< J))
• Ζεύγη προμηθευτή υλικού που ο προμηθευτής δεν προμηθεύει αυτό
το υλικό (σκεφτείτε)

Παραδείγματα
• Ζεύγη προμηθευτή - υλικού που ο προμηθευτής δεν προμηθεύει
αυτό το υλικό
• Ποιο είναι το εύκολο?
Απάντηση: ζεύγη προμηθευτή - υλικού που ο προμηθευτής
προμηθεύει αυτό το υλικό
ΠS#, P#(SPJ)
Ακολούθως αφαιρούμε από το σύνολο αυτών (καρτεσιανό γινόμενο)
ΠS#, P#(S X P) - ΠS#, P#(SPJ)

• Προσοχή: πρέπει να σχηματίσουμε συμβατά σύνολα για να μπορεί


να γίνει η διαφορά
Παραδείγματα
• Κωδικοί προμηθευτή για προμηθευτές που δίνουν τουλάχιστον ένα υλικό που
δίνεται από ένα τουλάχιστον προμηθευτή που δίνει κάποιο κόκκινο υλικό

• Φωλιασμένα ερωτήματα
• Λύση: ξεκινάμε ανάποδα και πηγαίνουμε προς τα πίσω

• Προμηθευτές που δίνουν ένα κόκκινο υλικό


ΠS# (σ color = ‘κοκκινο’(P >< SPJ )) = Α

• Υλικά που δίνουν αυτοί οι προμηθευτές


ΠP# (σ S# IN A (SPJ )) = B
• Προμηθευτές που δίνουν αυτά τα υλικά
ΠS# (σ P# IN B (SPJ ))

Παραδείγματα
• Κωδικοί προμηθευτή με στάτους μικρότερο από αυτό του S1
ΠS# (σstatus < x (S) )
Χρειαζόμαστε μια τιμή που δεν ξέρουμε
• Πώς τη βρίσκουμε? Χ = Πstatus (σs# = ‘S1’ (S) )

• Κωδικοί έργων που τα προμηθεύει αποκλειστικά ο S1


(σκεφτείτε)
Παραδείγματα
• Κωδικοί έργων που τα προμηθεύει αποκλειστικά ο S1
• Τι ζητάω? → Έργα που παίρνουν μόνο από τον S1
• Πώς το βρίσκω? → Αν κάποιος άλλος δίνει σε κάποιο έργο, διώχνω αυτό το έργο

• «Διώχνω» σημαίνει διαφορά


• Ποια είναι αυτά που θέλω να διώξω?

ΠJ# (σs# ≠ ‘S1’ (SPJ) )


• Πώς βρίσκω όλα τα έργα?
ΠJ# (J) ή ορθότερα ΠJ# (SPJ)

• Τελικά αφαίρεση: ΠJ# (SPJ) -ΠJ# (σs# ≠ ‘S1’ (SPJ) )

Φυσική σύνδεση και άλλες


εντολές
Περισσότεροι πίνακες
• Θυμίζουμε:
Φυσική σύνδεση
Customer >< Borrow

• Φέρνουμε δίπλα σε κάθε δάνειο τα στοιχεία του πελάτη που το έχει


Πώς?
• Από το καρτεσιανό γινόμενο («όλα-με-όλα») κρατάμε μόνο όσες
γραμμές έχουν ίδια τιμή στο κοινό πεδίο

Φυσική σύνδεση
• Δεν υπάρχει κάποια εντολή που κάνει φυσική σύνδεση
• Εφαρμόζουμε το μηχανισμό με τον οποίο γίνεται η σύνδεση

• Πίνακες: FROM Customer, Borrow


• Συνθήκη: WHERE [Link]-name = [Link]-name ΦΥΣΙΚΗ
ΣΥΝΔΕΣΗ

• Άρα: Αρ.δανείου, όνομα πελάτη, πόλη πελάτη

SELECT loan-no, [Link]-name, cust-city FROM Customer, Borrow


WHERE [Link]-name = [Link]-name AND
Φυσική σύνδεση
• Τα υπόλοιπα στοιχεία της εντολής SELECT συνεχίζουν
να βρίσκονται στην ίδια θέση με την ίδια λειτουργία
• Η συνθήκη σύνδεσης πρέπει να υπάρχει πάντα
• Οι υπόλοιπες συνθήκες συνδέονται με αυτήν με AND
• Μπορεί να έχουμε και περισσότερους από δύο
πίνακες – διαδοχικές συνδέσεις με τον ίδιο τρόπο

Παραδείγματα
• Αρ. λογαριασμού σε καταστήματα της Αθήνας
SELECT acc-no FROM Deposit, branch
WHERE [Link]-name = [Link]-name AND
Br-city = ‘Αθήνα’

• Αρ. δανείου και διεύθυνση πελάτη για πελάτες με δάνεια πάνω από
50000
SELECT loan-no, address FROM Borrow, customer
WHERE [Link]-name = [Link]-name AND
Amount > 50000
Παραδείγματα
• Αρ. λογαριασμού και όνομα πελάτη με λογαριασμό στην πόλη του
SELECT acc-no, [Link]-name FROM Deposit, branch, customer
WHERE [Link]-name = [Link]-name AND [Link]-name =
[Link]-name AND
Br-city = cust-city

• Ονόματα δανειοληπτών που έχουν τα δάνεια 961 και 1003 και τα αντίστοιχα
καταστήματα και πόλεις των δανείων
SELECT cust-name, [Link]-name, br-city FROM Borrow, branch
WHERE [Link]-name = [Link]-name AND
(loan-no = 961 OR loan-no = 1003)

Εμφωλευμένα ερωτήματα
• Πολλές φορές δεν χρειάζεται πραγματική η σύνδεση
• Αρ. λογαριασμού σε καταστήματα της Αθήνας
• Χρειαζόμαστε μόνο να ξέρουμε ποια καταστήματα είναι στην Αθήνα
SELECT br-name FROM branch
WHERE Br-city = ‘Αθήνα’

• Παράγεται μια λίστα ονομάτων που μπορούμε να χρησιμοποιήσουμε


• Συνεπώς
SELECT acc-no FROM Deposit
WHERE br-name IN (SELECT br-name FROM branch WHERE
Br-city = ‘Αθήνα’)
• Και πάλι πρέπει να υπάρχει συμβατότητα
Πράξεις συνόλων
• Τομή: INTERSECT
• Ένωση: UNION
• Διαφορά: MINUS

• Ισχύουν οι προϋποθέσεις συμβατότητας


• Ίδιο πλήθος χαρακτηριστικών
• Ίδιος τύπος δεδομένων

Παραδείγματα
• Ονόματα πελατών με δάνειο και λογαριασμό ταυτόχρονα στο ίδιο
κατάστημα
(SELECT cust-name FROM Deposit)
INTERSECT
(SELECT cust-name FROM Borrow)
• Ονόματα πελατών με δάνειο και λογαριασμό ταυτόχρονα στο ίδιο
κατάστημα
• Ψάχνουμε και το όνομα και το κατάστημα, σαν ζευγάρι
(SELECT cust-name, br-name FROM Deposit)
INTERSECT
(SELECT cust-name, br-name FROM Borrow)
Παραδείγματα
• Ονόματα πελατών είτε με δάνειο είτε με λογαριασμό
(SELECT cust-name FROM Deposit)
UNION
(SELECT cust-name FROM Borrow)
• Ονόματα πελατών με δάνειο αλλά χωρίς λογαριασμό
(SELECT cust-name FROM Borrow)
MINUS
(SELECT cust-name FROM Deposit)

Παραδείγματα
• Έργα που προμηθεύονται από τον προμηθευτή S1
αλλά όχι από κάποιον άλλο
SELECT J# FROM SPJ
MINUS
(SELECT J# FROM SPJ WHERE S# <> ‘S1’)
• Βρίσκουμε τα έργα που παίρνουν και από κάποιον
άλλο
• Αφαιρούμε αυτά τα έργα από την πλήρη λίστα έργων
Παραδείγματα
• Ζεύγη S# και P# ώστε ο προμηθευτής να ΜΗΝ προμηθεύει το υλικό
• Και πάλι πρέπει να βρούμε όλα τα ζευγάρια που ο προμηθευτής
προμηθεύει το υλικό και να τα αφαιρέσουμε από τα δυνατά ζευγάρια
• Ποια είναι αυτά τα ζευγάρια? Είναι αυτά που βρίσκω στο SPJ
SELECT S#, P# FROM SPJ
• Μετά αφαιρώ από όλα τα πιθανά (καρτεσιανό γινόμενο) ζεύγη (S#,
P#)
SELECT S#, P# FROM S, P
MINUS
S#, P# FROM SPJ

Παραδείγματα
• P# που δίνουν Αθηναίοι προμηθευτές ή παίρνουν έργα από Αθήνα
• Ο προφανής τρόπος: χρειαζόμαστε τους πίνακες SPJ, J, S → φυσική σύνδεση
SELECT P# FROM S, SPJ, J
WHERE S.S# = SPJ.S# AND J.J# = SPJ.J# AND
([Link] = ‘Αθήνα’ OR [Link] = ‘Αθήνα’)

• Πιο οικονομικός τρόπος: η Αθήνα δεν μας χρειάζεται, πέρα από το να βρούμε τα
έργα και τους προμηθευτές που είναι από εκεί.
SELECT P# FROM SPJ
WHERE S# IΝ (λίστα Αθηναίων προμηθευτών) OR J# IN (λίστα αθηναϊκών έργων)
• Η πρώτη είναι SELECT S# FROM S WHERE CITY = ‘Αθήνα’. Η δεύτερη είναι SELECT J#
FROM J WHERE CITY = ‘Αθήνα’
Παραδείγματα
• Μπορούμε να χειριστούμε το παράδειγμα και κάνοντας ένωση των συνόλων που
προκύπτουν από τις δύο συνθήκες
(SELECT P# FROM SPJ
WHERE S# IN (SELECT S# FROM S WHERE CITY = ‘Αθήνα’))
UNION
(SELECT P# FROM SPJ
WHERE J# IN (SELECT J# FROM J WHERE CITY = ‘Αθήνα’))

• Πόλεις που έχουν τουλάχιστον ένα υλικό / έργο/ προμηθευτή


• Χρειαζόμαστε τις λίστες των πόλεων για το καθένα και ακολούθως την ένωση τους
(SELECT CITY FROM P) UNION (SELECT CITY FROM J) UNION (SELECT CITY FROM S)

Παραδείγματα
• Έργα που παίρνουν κόκκινα υλικά από Αθηναίους
προμηθευτές
• Χρειαζόμαστε τους πίνακες SPJ, P (για το χρώμα) και S
( για την Αθήνα)
SELECT J# FROM SPJ, P, S
WHERE S.S# =SPJ.S# AND P.P# = SPJ.P# AND
(COLOR = ‘κόκκινο’ AND [Link] = ‘Αθήνα’)
Σύνδεση μεταξύ γραμμών του πίνακα
• Ζεύγη P# για υλικά που προμηθεύει ο ίδιος προμηθευτής

S1 P1
S1 P2
S2 P3
S2 P4
S3 P1
S4 P1
S4 P3
S5 P2
• Αν ο πίνακας SPJ έχει την παραπάνω μορφή, πρέπει να σχηματίσουμε τα
ζευγάρια (P1, P2) από τον S1, (P3,P4) από τον S2, (P1, P3) από τον S4. Από
τους S3 και S5, δεν θα προκύψει ζευγάρι γιατί δεν φαίνεται να δίνουν άλλο
υλικό.

Σύνδεση μεταξύ γραμμών του πίνακα


• Τι ζητάμε λοιπόν?
• Να συσχετίσουμε διαφορετικές γραμμές του ίδιου
πίνακα με βάση την ίδια τιμή στο πεδίο S#
• Συνεπώς χρειαζόμαστε έναν πίνακα που να περιέχει
αυτές τις γραμμές και να κάνουμε φυσική σύνδεση με
βάση το κοινό πεδίο. Αυτός ο πίνακας είναι μια
δεύτερη έκδοση του SPJ !
SELECT A.P#, B.P# FROM SPJ AS A, SPJ AS B
WHERE A.S# = B.S#
Σύνδεση μεταξύ γραμμών του πίνακα
• Προσοχή: αναγκαστικά ενώνεται και η κάθε γραμμή με τον εαυτό της
• Προκύπτει γραμμή με ίδια P# και αυτή δεν μας χρειάζεται:
WHERE A.P# <> B.P#
• Επειδή οι γραμμές είναι ίδιες, θα προκύψει ζεύγος (P1, P2) αλλά και το αντίστροφο (P2,P1) και
πρέπει να διώξουμε το ένα (αδιάφορο ποιο).
• Πάντα το ένα θα είναι μεγαλύτερο από το άλλο. Άρα μπορούμε να σβήσουμε αυτό που έχει το
πρώτο «μεγαλύτερο», άρα κρατάμε αυτό που έχει το πρώτο «μικρότερο»
WHERE A.P# < B.P#
Ουσιαστικά αυτή η συνθήκη περιλαμβάνει και την πρώτη
Άρα τελικά
SELECT A.P#, B.P# FROM SPJ AS A, SPJ AS B
WHERE A.S# = B.S# AND
( A.P# < B.P#)

Άλλες εντολές SQL


Εντολές τροποποίησης δεδομένων
• Η SELECT δεν επηρεάζει τα αποθηκευμένα δεδομένα
• Εισαγωγή, διαγραφή, τροποποίηση: αλλάζουν τα δεδομένα στη
βάση
• Υπάρχει δυνατότητα για αναίρεση πριν το κλείσιμο και την οριστική
αποθήκευση (rollback)

Εισαγωγή νέων δεδομένων


• Εισαγωγή σημαίνει ΝΕΕΣ ΓΡΑΜΜΕΣ
• Εφαρμόζονται όποιοι έλεγχοι απαιτείται
➢Μοναδικές τιμές κλειδιού
➢Τύποι δεδομένων
➢Κενές τιμές
INSERT INTO <πίνακας> [ ( <λίστα πεδίων> ) ]
VALUES ( < λίστα τιμών> )
Εντολή INSERT
• Παράδειγμα: εισαγωγή γραμμής στον πίνακα Borrow με αριθμό
δανείου και όνομα πελάτη, με κενά τα υπόλοιπα πεδία
INSERT INTO Borrow (cust-name, loan-no)
VALUES (‘Πέτρου’, 23910)
• Οι τιμές αντιστοιχούν μία προς μία στα πεδία όπως αυτά γράφονται
στην εντολή
• Πρέπει να περιλαμβάνονται τουλάχιστον οι μη κενές (NOT NULL)
τιμές, αλλιώς η εντολή δεν δουλεύει

Εντολή INSERT
• Παράδειγμα: εισαγωγή γραμμής στον πίνακα Borrow με αριθμό
δανείου και όνομα πελάτη, με κενά τα υπόλοιπα πεδία
INSERT INTO Borrow (cust-name, loan-no)
VALUES (‘Πέτρου’, 23910)
• Οι τιμές αντιστοιχούν μία προς μία στα πεδία όπως αυτά γράφονται
στην εντολή
• Πρέπει να περιλαμβάνονται τουλάχιστον οι μη κενές (NOT NULL)
τιμές, αλλιώς η εντολή δεν δουλεύει
Εντολή INSERT
• Μπορεί να παραλειφθεί η λίστα πεδίων, αρκεί να δίνονται όλες οι
τιμές της γραμμής, με τη σειρά που έχουν ορισθεί στον πίνακα
INSERT INTO Branch
VALUES (‘Κέντρο’, ‘Αθήνα’, 1000000)
• Μπορεί να ζητήσουμε να μείνει ένα πεδίο κενό
INSERT INTO Borrow
VALUES (12555, null, null, 1000.00)

Εντολή INSERT
• Υπάρχει και η δυνατότητα να δώσουμε «πακέτο» το αποτέλεσμα μιας
εντολή SELECT (προσοχή: συμβατότητα)
• Παράδειγμα: δημιουργούμε έναν νέο πίνακα Branch_Athens, με στήλες
br-name, assets και θέλουμε να εισάγουμε αυτά τα στοιχεία για τα
καταστήματα της Αθήνας
• Καταστήματα Αθήνας: SELECT br-name, assets FROM branch
WHERE br-city = ‘Αθήνα’
• Εισαγωγή στον νέο πίνακα
INSERT INTO Branch_Athens
(SELECT br-name, assets FROM branch WHERE br-city = ‘Αθήνα’)
Εντολή INSERT: παραδείγματα
• Εισαγωγή του προμηθευτή S5, με στάτους 3 και πόλη Αθήνα
INSERT INTO S (S#, status, city)
VALUES (‘S5’, 3 , ‘Αθήνα’)
• Εναλλακτικά INSERT INTO S VALUES (‘S5’, null, ‘Αθήνα’, 3) (ακολουθούμε τη σειρά
των πεδίων στον πίνακα)
• Προσοχή: όχι εισαγωγικά στο null, γιατί θα θεωρηθεί λέξη
• Παρά ταύτα, η εντολή θα τρέξει, βάζοντας σαν Sname το null

• Παραγγελία από S1, για το υλικό Ρ2, στο έργο J5 , χωρίς να ορίσουμε ποσότητα
INSERT INTO SPJ VALUES (‘S1’, ‘P2’, ‘J5’, null)
ή INSERT INTO SPJ (S#, P#, J#) VALUES (‘S1’, ‘P2’, ‘J5’)

Εντολή INSERT: παραδείγματα


• Εισαγωγή στις παραγγελίες όλων των πιθανών συνδυασμών S#, P#,
J# χωρίς τιμή στην ποσότητα Χωρίς συνθήκη σύνδεσης,
καρτεσιανό γινόμενο!
• INSERT INTO SPJ (S#, P#, J#)
SELECT S#, P#, J# FROM S, P, J
• Εναλλακτικά
INSERT INTO SPJ
SELECT S#, P#, J#, null FROM S, P, J
• Θυμηθείτε: στη SELECT μπορούμε να έχουμε και εκφράσεις ή και
απλές τιμές (το null είναι η απουσία τιμής, αλλά εδώ α΄πλώς
σχηματίζει την τετράδα για τη γραμμή του SPJ)
Διαγραφή δεδομένων
• Διαγραφή: Σβήσιμο ολόκληρων γραμμών (όχι τιμών)
• Πρώτα αναζήτηση – μετά σβήσιμο
DELETE <πίνακας>
[WHERE <συνθήκη> ]
• ΠΡΟΣΟΧΗ: δεν περιλαμβάνεται στο standard
• Μπορεί να τη δούμε και με τη μορφή DELETE FROM
• Παράδειγμα: διαγραφή όλων των δανείων του πελάτη Πέτρου
DELETE Borrow
WHERE Cust-name = ‘Πέτρου’

Εντολή DELETE
• H συνθήκη μπορεί να είναι ο,τιδήποτε
• Το WHERE λειτουργεί ακριβώς όπως και στη SELECT
(θυμηθείτε: τουβλάκια)
DELETE Customer
WHERE Cust-name LIKE ‘A%’ (τι κάνει;)
• Απάντηση: Διαγράφει πελάτες με όνομα που αρχίζει από Α

DELETE Borrow
WHERE amount < 1000 AND amount >500
Εντολή DELETE
• To WHERE δεν είναι απαραίτητο για να λειτουργήσει
η εντολή:
DELETE Borrow
(τι πιστεύετε ότι κάνει; Σκεφτείτε)

• Απάντηση: διαγραφή όλων των γραμμών (όχι του


πίνακα, η δομή παραμένει)

Ενημέρωση δεδομένων
• Ενημέρωση: αλλαγή δεδομένων που υπάρχουν ήδη
• Όχι προσθήκη/διαγραφή γραμμών
UPDATE <πίνακας>
SET <λίστα αναθέσεων>
[WHERE <συνθήκη> ]
Εντολή UPDATE: τεχνικές λεπτομέρειες
• Μπορώ να κάνω περισσότερες αλλαγές ταυτόχρονα
(πάντα στην ίδια γραμμή/ές)
• Μπορώ να κάνω υπολογισμό και με το αποτέλεσμα
να κάνω ενημέρωση
UPDATE Borrow
SET Br-name = ‘Ομόνοια’ , amount = amount * 1,2
WHERE Br-name = ‘Κέντρο’

Ενημέρωση δεδομένων: UPDATE


• Αλλαγή του ποσού του δανείου του πελάτη Πέτρου
UPDATE Borrow
SET amount = 2000
WHERE Cust-name = ‘Πέτρου’
• Αλλαγή του ονόματος ενός πελάτη με ένα νέο
UPDATE Borrow
SET Cust-name = ‘Πετρίδης’
WHERE Cust-name = ‘Πέτρου’
Ενημέρωση δεδομένων: UPDATE
• Προσοχή στη συνθήκη: αν δεν μπει,…
UPDATE Borrow
SET amount = 2000

• Απάντηση: η αλλαγή εφαρμόζεται σε όλες τις


γραμμές του πίνακα!

Εντολές ορισμού δεδομένων


• Ενέργειες για τις δομές που δημιουργούμε σε μια βάση
δεδομένων
➢Δημιουργία πίνακα
➢Τροποποίηση πίνακα
➢Διαγραφή πίνακα
• Δεν ασχολούνται με δεδομένα
• Δημιουργούν/τροποποιούν δομές
Δημιουργία πίνακα
CREATE TABLE <όνομα πίνακα>
( <όνομα πεδίου> <τύπος πεδίου> [ΝΟΤ NULL],
<όνομα πεδίου> <τύπος πεδίου> [ΝΟΤ NULL],

<όνομα πεδίου> <τύπος πεδίου> [ΝΟΤ NULL],
[PRIMARY KEY (<λίστα πεδίων>),]
[FOREIGN KEY (<όνομα πεδίου> ) REFERENCES <όνομα
πίνακα>] )

Δημιουργία πίνακα
• Πρέπει να ορίσουμε τύπο για κάθε χαρακτηριστικό
• Τύποι: Real, float, number, integer (int), date, varchar (n),
logical, Boolean, …
• ΝΟΤ ΝULL: δεν είναι υποχρεωτικό, χρειάζεται για να είμαστε βέβαιοι
ότι θα δίνεται τιμή στο χαρακτηριστικό αυτό σε όλες τις γραμμές
• NULL: κενή τιμή, όχι 0 ή spacebar
Δημιουργία πίνακα
• Πρωτεύον κλειδί (primary key): μοναδικές τιμές, ποτέ κενό
• Μπορεί να είναι και πάνω από ένα πεδίο

• Ξένο κλειδί (foreign key): οι τιμές σε αυτό το χαρακτηριστικό


πρέπει να υπάρχουν ήδη στο χαρακτηριστικό που
αναφέρεται στο REFERENCES

Δημιουργία πίνακα
• Για τον πίνακα SPJ:
CREATE TABLE SPJ
(S# Varchar (6) NOT NULL,
P# Varchar (6) NOT NULL,
J# Varchar (6) NOT NULL,
posot integer,
PRIMARY KEY (S#,P#,J#),
FOREIGN KEY (S#) REFERENCES S (S#),
FOREIGN KEY (J#) REFERENCES J (J#),
FOREIGN KEY (P#) REFERENCES P (P#) )
Δημιουργία πίνακα: παρατηρήσεις (1)
• Ο τύπος δεδομένων σχεδόν απαραίτητος: αν δεν ορισθεί, το
σύστημα βάζει κάποιον default, πχ char(1), που είναι άχρηστος
• Not null: αυτό το πεδίο πρέπει να έχει πάντα τιμή
➢ Το κρίνει ο σχεδιαστής
➢ Πχ. Στη Γραμματεία θέλουμε σίγουρα ΑΜ και όνομα, αλλά
ξέρουμε ότι πάντα ο φοιτητής βρίσκεται σε κάποιο
εξάμηνο, άρα θέλουμε και το εξάμηνο not null
➢ Γενικά πάντως δεν βάζουμε not null τυχαία, πρέπει να
στηριζόμαστε κάπου

Δημιουργία πίνακα: παρατηρήσεις (2)


• Πρωτεύον κλειδί: μοναδικές τιμές, όχι κενά
➢Αν χρειάζεται, ζευγάρι (ή τριάδα) τιμών: ένα κλειδί, με δύο μέρη
• Ξένο κλειδί: πεδίο που το «παίρνουμε» από κάποιον άλλο πίνακα
➢ S# στον SPJ: για να έχει παραγγελίες, υπάρχει σίγουρα στον
πίνακα S
➢ Αν η τιμή που θέλουμε να βάλουμε σε τέτοιο πεδίο δεν υπάρχει
στο αρχικό πίνακα, το σύστημα δεν μας το επιτρέπει
➢ Το REFERENCES δείχνει σε ποιον πίνακα κοιτάμε και σε ποιο πεδίο
εκείνου του πίνακα
Διαγραφή πίνακα
• Διαγραφή όλου του πίνακα, τόσο δεδομένα όσο και
δομή
DROP TABLE <όνομα πίνακα>
• Διαγραφή όλου του πίνακα, τόσο δεδομένα όσο και
δομή
• Ιδιαίτερη προσοχή – πάντα το σύστημα προειδοποιεί

ΣΥΓΚΕΝΤΡΩΤΙΚΕΣ ΣΥΝΑΡΤΗΣΕΙΣ
GROUP BY - HAVING
Παραδείγματα
• Συνολικό πλήθος έργων που προμηθεύει ο προμηθευτής S1
select COUNT(J#) from SPJ where S# = ‘S1’
• Μετά την επιλογή, δεν χρειάζεται ομαδοποίηση, όλος ο πίνακας που
μένει είναι μια ομάδα

• Είναι όμως η σωστή απάντηση ?

Παραδείγματα
S# P# J# POSOT
S1 P1 J2 300
S1 P2 J1 400
S2 P3 J2 200
S2 P2 J1 150
S3 P4 J3 200
S1 P2 J1 230

• Τα έργα του S1 είναι το J1 και το J2


• Αν μετρήσουμε τις γραμμές, βρίσκουμε 3.
• Λύση: DISTINCT – μετράμε κάθε τιμή μόνο μία φορά
• Τελικά: select COUNT(DISTINCT J#) from SPJ where S# = ‘S1’
Παραδείγματα
• Συνολική ποσότητα για κάθε υλικό που προμηθεύει ο S1
select SUM(posot) from SPJ where S# = ‘S1’
GROUP BY P#

• SELECT: επιδρά σε γραμμές πίνακα


• Μπορούμε να κάνουμε και υπολογισμούς
• Παράδειγμα: Άθροισμα των ποσών των καταθέσεων σε κάθε
κατάστημα

Παραδείγματα
• Για κάθε υλικό που παρέχεται σε κάποιο έργο, κωδικός υλικού,
κωδικός έργουΣυνολική ποσότητα για κάθε υλικό που προμηθεύει ο
S1
select SUM(posot) from SPJ where S# = ‘S1’
GROUP BY P#

• SELECT: επιδρά σε γραμμές πίνακα


• Μπορούμε να κάνουμε και υπολογισμούς
• Παράδειγμα: Άθροισμα των ποσών των καταθέσεων σε κάθε
κατάστημα
Ομαδοποίηση
• «για κάθε» κατάστημα → δημιουργία ομάδων
✓ Ομάδα «Κέντρο»: 100+250 = 350
✓ Ομάδα «Ομόνοια»: 180
✓ Ομάδα «Πύργος»: 310
• Άρα αποτέλεσμα:
Κέντρο 350
Ομόνοια 180
Πύργος 310

Συγκεντρωτικές (aggregate) συναρτήσεις


• Η SQL υποστηρίζει:
✓ Άθροισμα SUM()
✓ Μέσος όρος AVG()
✓ Ελάχιστο ΜΙΝ()
✓ Μέγιστο ΜΑΧ()
✓ Μετρητής COUNT()
• Πώς γίνονται οι ομάδες?
Ο όρος GROUP BY
• Σχηματίζω ομάδες με βάση τις τιμές κάποιου πεδίου
• Θέλω άθροισμα καταθέσεων για κάθε κατάστημα
SELECT
FROM Deposit
GROUP BY Br-name
• Σχηματίζω ομάδες και μετά εκτελώ το SELECT
SELECT sum(balance) (Κέντρο) 350
FROM Deposit Αποτέλεσμα (Ομόνοια) 180
GROUP BY Br-name (Πύργος) 310

Για κάθε κατάστημα, δείξε ένα άθροισμα

SELECT συμβατό με GROUP BY (1)


• Προσοχή: όλη η εντολή πρέπει να συμφωνεί με την ομαδοποίηση
→ δεν μπορώ να έχω τα πάντα στο SELECT
• Ερώτημα: Τι μπορώ να έχω στο SELECT?
• Σίγουρα συναρτήσεις – αφορούν σε ομάδες
• Τι άλλο? Τι από όλα τα πεδία είναι συμβατό με το group by?
(σκεφτείτε)
SELECT συμβατό με GROUP BY (2)
Μπορώ να έχω το παρακάτω?
SELECT cust-name, SUM(balance)
FROM Deposit
GROUP BY Br-name
To παρακάτω?
SELECT br-name, SUM(balance)
FROM Deposit
GROUP BY Br-name

SELECT συμβατό με GROUP BY (3)


• Το cust-name μπορεί να ομαδοποιηθεί με βάση το Br-name?
ΌΧΙ!
• Το br-name μπορεί να ομαδοποιηθεί με βάση το Br-name?
NAI!

Συμπέρασμα: μόνο το πεδίο ομαδοποίησης και συναρτήσεις


Συναρτήσεις χωρίς GROUP BY (1)
• Μπορώ να μην βάλω group by αν έχω συναρτήσεις?

SELECT AVG (amount)


FROM Borrow

• Όλος ο πίνακας μια ομάδα


• Υπολογίζεται ένα μέγεθος για όλο τον πίνακα
• Χρήση: μπορώ να το χρησιμοποιώ όπου χρειάζομαι αυτό το μέγεθος
• Συνέπεια: χωρίς Group By, μόνο συναρτήσεις στο SELECT

Συναρτήσεις χωρίς GROUP BY (1)


• Μπορώ να μην βάλω group by αν έχω συναρτήσεις?

SELECT AVG (amount)


FROM Borrow

• Όλος ο πίνακας μια ομάδα


• Υπολογίζεται ένα μέγεθος για όλο τον πίνακα
• Χρήση: μπορώ να το χρησιμοποιώ όπου χρειάζομαι αυτό το μέγεθος
• Συνέπεια: χωρίς Group By, μόνο συναρτήσεις στο SELECT
Συνθήκες
• Το WHERE εφαρμόζεται αν χρειάζεται
• Δεν επηρεάζεται από το GROUP BY
• Παράδειγμα: πόσους λογαριασμούς έχουν ο Πέτρου και ο Παύλου
SELECT COUNT(Cust-name) , Cust-name
FROM Deposit
WHERE Cust-name IN (‘Πέτρου’, ‘Παύλου’)
ORDER BY Cust-name
GROUP BY Cust-name
• Πρώτα σχηματίζεται ο πίνακας με την επιλογή γραμμών
• Μετά στον νέο πίνακα γίνεται η ομαδοποίηση
• Τα ίδια ισχύουν για το ORDER BY

Τι λαμβάνεται υπόψη?
• Τι βγάζει η εντολή SELECT Br-name, AVG(balance) FROM Deposit
GROUP BY Br-name
Τι λαμβάνεται υπόψη?
• H τιμή ‘Κέντρο’ έχει 3 γραμμές, αλλά 2 τιμές (μία κενή)
• Άρα μέσος όρος (100+250) / 2 = 175

• Δεν λαμβάνονται υπ’ όψη οι null τιμές

Μετρητής (COUNT)
• Η count() μετράει γραμμές
• Πόσες παραγγελίες έχει κάθε έργο?
SELECT J#, COUNT(J#)
FROM SPJ
GROUP BY J#
• Έχει διαφορά αν βάλουμε COUNT(S#) ?
• Απάντηση: ΟΧΙ! Μετράμε τιμές του πεδίου, δηλαδή γραμμές
• Γι’ αυτό υπάρχει και η δυνατότητα COUNT (*)
Μετρητής (COUNT)
• Προσοχή: τα κενά δεν συμμετέχουν σε καμία συνάρτηση
• Γι’ αυτό έχει σημασία ποιο πεδίο επιλέγουμε στο COUNT

• Αν μας ενδιαφέρουν μόνο οι γραμμές, μετράμε το πρωτεύον κλειδί ή


βάζουμε *
• Κάποιες φορές η διατύπωση του ερωτήματος μας δείχνει ποιο πεδίο
να επιλέξουμε
• Προσοχή: το COUNT είναι εντελώς διαφορετικό από το SUM

HAVING
• Πώς να επιλέξω ομάδες?
• Παράδειγμα: Πόσες παραγγελίες έχει κάθε έργο,
αλλά μόνο για έργα με πάνω από 5 παραγγελίες
• Το WHERE επιλέγει γραμμές → δεν είναι κατάλληλο
• Τη δουλειά αυτή κάνει το HAVING
HAVING
SELECT J#, COUNT (J#)
FROM SPJ
GROUP BY J#
HAVING COUNT(J#) >5

• Μόνο συναρτήσεις έχουν νόημα στη συνθήκη του HAVING


(θυμηθείτε: συμβατή με το GROUP BY)
• Μπορεί και πάνω από μία συνθήκη: HAVING COUNT(J#) >5 AND
COUNT(J#) <8

ΣΥΓΚΕΝΤΡΩΤΙΚΕΣ ΣΥΝΑΡΤΗΣΕΙΣ
GROUP BY - HAVING
Παραδείγματα
• Συνολικό πλήθος έργων που προμηθεύει ο προμηθευτής S1
select COUNT(J#) from SPJ where S# = ‘S1’
• Μετά την επιλογή, δεν χρειάζεται ομαδοποίηση, όλος ο πίνακας που
μένει είναι μια ομάδα

• Είναι όμως η σωστή απάντηση ?

Παραδείγματα
S# P# J# POSOT
S1 P1 J2 300
S1 P2 J1 400
S2 P3 J2 200
S2 P2 J1 150
S3 P4 J3 200
S1 P2 J1 230

• Τα έργα του S1 είναι το J1 και το J2


• Αν μετρήσουμε τις γραμμές, βρίσκουμε 3.
• Λύση: DISTINCT – μετράμε κάθε τιμή μόνο μία φορά
• Τελικά: select COUNT(DISTINCT J#) from SPJ where S# = ‘S1’
Παραδείγματα
• Συνολική ποσότητα για κάθε υλικό που προμηθεύει ο S1
select SUM(posot) from SPJ where S# = ‘S1’
GROUP BY P#

• Πλήθος προμηθευτών που δίνουν κόκκινα υλικά για κάθε έργο


Select J#, COUNT(S#) from SPJ, P where SPJ.P# = P.P# AND
color = ‘κόκκινο’
GROUP BY J#
Προσοχή: η σύνδεση πινάκων δεν επηρεάζεται, το group by εφαρμόζεται
στον συνολικό πίνακα

Παραδείγματα
• Για κάθε υλικό που παρέχεται σε κάποιο έργο, κωδικός υλικού, κωδικός
έργου και συνολική ποσότητα για κάθε υλικό
select P#, J#, SUM(posot) from SPJ
GROUP BY P#, J#
• Έχω δυνατότητα να ζητάω ομαδοποίηση ως προς τις τιμές ενός ζεύγους
πεδίων

• Για κάθε έργο που έχει πάνω από δύο προμηθευτές, κωδικός έργου και
πλήθος παραγγελιών
Select J#, COUNT (posot) from SPJ GROUP BY J# HAVING COUNT (DISTINCT S#) >2
Παραδείγματα
• Κωδικοί έργων και μέσος όρος κομματιών παραγγελίας του έργου μόνο
για τα έργα που έχουν πάνω από 3 παραγγελίες
select J#, AVG(posot) from SPJ
GROUP BY J# HAVING COUNT(posot) > 3

• Όλα τα στοιχεία των παραγγελιών που έχουν ποσότητες παραγγελίας


μεγαλύτερες από το μέσο όρο όλων των παραγγελιών
Select * from SPJ where posot > (select avg(posot) from SPJ)
• Προσοχή: δεν υπάρχει ανάγκη ομαδοποίησης στο αρχικό ερώτημα
ΤΕΙ Ηπείρου
Τμήμα Μηχανικών Πληροφορικής Τ.Ε.

Βάσεις Δεδομένων Ι
[Σημειώσεις Εργαστηρίου]

Επιμέλεια:
Καρβούνης Ευάγγελος, PhD, Επιστημονικός Συνεργάτης του Τμήματος
Αντωνιάδης Νικόλαος, Καθηγητής

Οκτώβριος 2013
Περιεχόμενα
1 Σχεδιασμός Βάσης.......................................................................................... 2
1.1 Δημιουργία πινάκων ......................................................................................... 2
1.2 Επεξεργασία πινάκων ....................................................................................... 4
1.2.1 Εισαγωγή πεδίου ................................................................................................................ 4
1.2.2 Τροποποίηση πεδίου .......................................................................................................... 5
1.2.3 Διαγραφή πεδίου ............................................................................................................... 5

1.3 Διαγραφή πινάκων ........................................................................................... 5

2 Χειρισμός Δεδομένων .................................................................................... 5


2.1 Εισαγωγή δεδομένων........................................................................................ 5
2.2 Επισκόπηση δεδομένων .................................................................................... 6
2.3 Τροποποίηση δεδομένων .................................................................................. 7
2.3.1 Τροποποίηση πλειάδων ..................................................................................................... 7
2.3.2 Διαγραφή πλειάδων ........................................................................................................... 9
2.3.3 Αποθήκευση αλλαγών ........................................................................................................ 9

3 Σύνδεση πινάκων – Ξένα κλειδιά ................................................................... 9


4 Η εντολή SELECT ............................................................................................12
4.1 Ερωτήσεις SELECT με έναν πίνακα ................................................................... 12
4.1.1 Σύνθετες συνθήκες ........................................................................................................... 13
4.1.2 Πράξεις ............................................................................................................................. 13
4.1.3 Ο τελεστής LIKE................................................................................................................. 14
4.1.4 Η μεταβλητή SYSDATE ...................................................................................................... 14
4.1.5 Αλλαγή ονομάτων στηλών του αποτελέσματος............................................................... 14
4.1.6 Ταξινόμηση αποτελέσματος – ORDER BY......................................................................... 15
4.1.7 Ο τελεστής ΙΝ .................................................................................................................... 16
4.1.8 Ο τελεστής BETWEEN ....................................................................................................... 16
4.1.9 Εμφωλευμένες ερωτήσεις ................................................................................................ 16

4.2 Πράξεις μεταξύ SELECT ερωτήσεων ................................................................. 18


4.2.1 Ένωση SELECT ερωτήσεων ............................................................................................... 18
4.2.2 Τομή SELECT ερωτήσεων .................................................................................................. 19
4.2.3 Εξαίρεση SELECT ερωτήσεων ........................................................................................... 19

4.3 Ερωτήσεις SELECT με πολλούς πίνακες ............................................................ 19


4.4 Συναθροιστικές συναρτήσεις........................................................................... 22
4.4.1 Ομαδοποίηση ................................................................................................................... 24

| 1
[Type text]

1 Σχεδιασμός Βάσης
Θέλουμε να κατασκευάσουμε μία βάση δεδομένων για κινηματογραφικές ταινίες και
ηθοποιούς του Hollywood. Για λόγους απλότητας, ας θεωρήσουμε αρχικά ότι το μόνο που
θέλουμε να αποθηκεύσουμε είναι διάφορα στοιχεία μόνο για τους ηθοποιούς και τις
ταινίες.
Είναι πολύ σημαντικό, πριν ξεκινήσουμε να κατασκευάζουμε τη βάση μας, να έχουμε
ξεκάθαρα στο μυαλό μας τι ακριβώς θέλουμε να έχουμε αποθηκευμένο σε αυτήν. Για
παράδειγμα, στην περίπτωσή μας θα χρειαστούμε τα παρακάτω:
 Για κάθε ηθοποιό θέλουμε τον αριθμό ταυτότητάς του, που είναι μοναδικός για
κάθε ηθοποιό, το ονοματεπώνυμό του, την ημερομηνία και τον τόπο γέννησής του
καθώς και τον αριθμό των βραβείων oscar που ενδεχομένως έχει κερδίσει στην
καριέρα του.
 Για κάθε ταινία θέλουμε τον τίτλο της, το έτος παραγωγής της, το όνομα του
σκηνοθέτη της, το συνολικό της κόστος (budget) και τον αριθμό των εισιτηρίων που
πέτυχε. Θεωρούμε ότι δεν υπάρχουν πολλές ταινίες με τον ίδιο τίτλο.
Από την παραπάνω περιγραφή γίνεται αντιληπτό ότι στη βάση μας θα πρέπει να έχουμε
δύο πίνακες: έναν για τους ηθοποιούς και έναν για τις ταινίες. Πρέπει να διαλέξουμε ένα
όνομα για κάθε πίνακα. Έστω λοιπόν ότι τον πίνακα των ηθοποιών θα τον ονομάσουμε
ACTORS και τον πίνακα των ταινιών MOVIES (ως συνήθως, ελληνικοί χαρακτήρες δεν είναι
αποδεκτοί σε ονόματα πινάκων, πεδίων κτλ).
Προσέξτε ότι οι δύο αυτοί πίνακες είναι η υλοποίηση των αντίστοιχων οντοτήτων. Για το
λόγο αυτό, ο κάθε πίνακας περιέχει μόνο δεδομένα που αφορούν την αντίστοιχη οντότητα
και όχι δεδομένα που αφορούν τη σύνδεση μεταξύ των οντοτήτων (π.χ. δεν αναφέρονται οι
ταινίες στις οποίες παίζει ο κάθε ηθοποιός).
Στη συνέχεια, πρέπει να διαλέξουμε ένα όνομα για κάθε πεδίο (δηλαδή για την κάθε στήλη
του κάθε πίνακα). Στα πλαίσια του εργαστηρίου θα χρησιμοποιήσουμε τα εξής ονόματα:
ACTORS MOVIES
ID αριθμός ταυτότητας TITLE τίτλος ταινίας
NAME ονοματεπώνυμο YEAR έτος παραγωγής
BIRTHDATE ημερομηνία γέννησης DIRECTOR σκηνοθέτης
BIRTHPLACE τόπος γέννησης BUDGET κόστος
OSCARS αριθμός βραβείων oscar TICKETS αριθμός εισιτηρίων

1.1 Δημιουργία πινάκων


Για να δημιουργήσουμε έναν πίνακα χρησιμοποιούμε την εντολή CREATE TABLE. Η
σύνταξή της είναι η εξής:
CREATE TABLE <όνομα πίνακα> (
<όνομα 1ου πεδίου> <τύπος 1ου πεδίου>,
<όνομα 2ου πεδίου> <τύπος 2ου πεδίου>,
…,
<όνομα νου πεδίου> <τύπος νου πεδίου>,
2 Σχεδιασμός Βάσης |
primary key (<όνομα πεδίου>)
);

Γενικά για τις εντολές SQL, δεν χρειάζεται να γράφονται σε διαφορετικές γραμμές, όπως
στο παράδειγμα που φαίνεται παραπάνω. Μπορούν να γράφονται όπως μας βολεύει.
Ωστόσο, η γραφή αυτή δίνει μια ομοιομορφία και επιτρέπει την καλύτερη επισκόπηση
των εντολών. Θα παρατηρήσετε ότι ανεξάρτητα από το πώς γράφετε την εντολή στο
πλαίσιο «Εκτέλεση εντολής / εντολών SQL στη βάση δεδομένων χχχ», μετά την εκτέλεση
της εμφανίζεται η ίδια εντολή (διαμορφωμένη αυτόματα από το σύστημα) με το
παραπάνω format στο πλαίσιο «Εντολή SQL».

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


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

integer ή int ακέραιος αριθμός


πραγματικός αριθμός (όχι απαραίτητα
real
ακέραιος)
char χαρακτήρας (ένας μόνο)
Συμβολοσειρά με μέγιστο μήκος όσο και
ο αριθμός που δίνουμε, π.χ. varchar(10)
varchar(<αριθμός>)
είναι μία συμβολοσειρά με μήκος το
πολύ 10 χαρακτήρων
date ημερομηνία

Υπάρχουν και αρκετοί άλλοι τύποι δεδομένων (ενδεικτικά οι SMALLINT, DOUBLE, BINARY,
LONGTEXT). Εδώ δείχνουμε μόνο τους τύπους που μας είναι απαραίτητοι, οι οποίοι
καλύπτουν και το πολύ μεγάλο μέρος των αναγκών στις συνηθισμένες εφαρμογές.
Εκτός από τον ορισμό του τύπου ενός πεδίου, μπορεί να υπάρχει και ο προσδιορισμός not
null, για τις περιπτώσεις πεδίων για τα οποία δεν επιτρέπεται να μην υπάρχουν
καταχωρημένες τιμές. Αν για παράδειγμα για κάθε ηθοποιό θέλουμε οπωσδήποτε να
γνωρίζουμε το όνομά του, θα προσθέσουμε τον προσδιορισμό not null στον ορισμό του
πεδίου NAME (δίπλα από τον τύπο του).
Primary key είναι το πρωτεύον κλειδί του πίνακα:
Πρωτεύον κλειδί είναι ένα πεδίο (ή ένας συνδυασμός πεδίων) τέτοιο ώστε κάθε δυνατή
πλειάδα (γραμμή) που μπορεί να υπάρξει στον πίνακα να έχει διαφορετική τιμή από τις
υπόλοιπες στο πεδίο αυτό. Επίσης, το πεδίο αυτό δεν μπορεί να μένει κενό (null).

Για παράδειγμα, ένα τέτοιο πεδίο για τον πίνακα ACTORS είναι το ID, καθώς δύο
διαφορετικοί ηθοποιοί δεν μπορεί να έχουν τον ίδιο αριθμό ταυτότητας. Αντίστοιχα, το
BIRTHDATE δεν μπορεί να είναι πρωτεύον κλειδί γιατί δύο ηθοποιοί μπορεί να έχουν
γεννηθεί την ίδια ημέρα και το ίδιο έτος. Κάθε πίνακας πρέπει οπωσδήποτε να έχει
πρωτεύον κλειδί. Επίσης, κάθε πίνακας έχει μόνο ένα πρωτεύον κλειδί (δεν μπορούν να
υπάρχουν δύο γραμμές primary key (<όνομα πεδίου>) σε μία εντολή CREATE TABLE).

| Σχεδιασμός Βάσης 3
[Type text]

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

CREATE TABLE ACTORS (


ID varchar(10),
NAME varchar(20) not null,
BIRTHDATE date,
BIRTHPLACE varchar(20),
OSCARS int,
primary key (ID)
);
Για να δούμε το σχήμα (δηλαδή την περιγραφή) ενός πίνακα, μπορούμε να
χρησιμοποιήσουμε την εντολή DESCRIBE. Η σύνταξή της είναι η εξής:
DESCRIBE <όνομα πίνακα>;
Για παράδειγμα:
DESCRIBE ACTORS;

Γράψτε την εντολή για τη δημιουργία του πίνακα MOVIES:

1.2 Επεξεργασία πινάκων


Αφού έχει δημιουργηθεί ένας πίνακας στην βάση μας, μπορούμε να κάνουμε ορισμένες
αλλαγές σε αυτόν όπως να προσθέσουμε ή να διαγράψουμε ένα πεδίο ή να
τροποποιήσουμε τον τύπο ενός πεδίου. Για αυτόν τον σκοπό χρησιμοποιούμε την εντολή
ALTER TABLE.
1.2.1 Εισαγωγή πεδίου
Για να προσθέσουμε ένα πεδίο (μία στήλη) σε έναν πίνακα η σύνταξη της εντολής είναι:
ALTER TABLE <όνομα πίνακα> ADD <όνομα νέου πεδίου> <τύπος νέου
πεδίου>;
Επομένως, για να προσθέσουμε στον πίνακα MOVIES μία επιπλέον στήλη στην οποία θα
αποθηκεύουμε τη διάρκεια κάθε ταινίας, η εντολή είναι:

4 Σχεδιασμός Βάσης |
ALTER TABLE MOVIES ADD DURATION varchar(6);
1.2.2 Τροποποίηση πεδίου
Για να αλλάξουμε τον τύπο ενός πεδίου η σύνταξη της εντολής είναι:
ALTER TABLE <όνομα πίνακα> MODIFY <όνομα πεδίου> <τύπος νέου
πεδίου>;
Για παράδειγμα, αν θέλουμε να μετατρέψουμε το πεδίο DURATION από varchar(6) σε int
(πόσα λεπτά διαρκεί η ταινία σε ακέραιο αριθμό), γράφουμε:
ALTER TABLE MOVIES MODIFY DURATION int;
Με αυτή τη σύνταξη μπορούμε να τροποποιήσουμε μόνο τον τύπο ενός πεδίου και όχι το
όνομά του.
1.2.3 Διαγραφή πεδίου
Για να διαγράψουμε ένα πεδίο από έναν πίνακα η σύνταξη της εντολής είναι:
ALTER TABLE <όνομα πίνακα> DROP COLUMN <όνομα πεδίου>;
Έτσι, για να διαγράψουμε το πεδίο DURATION από τον πίνακα MOVIES, εκτελούμε την
εντολή:
ALTER TABLE MOVIES DROP COLUMN DURATION;
Η εντολή αυτή αφορά τη διαγραφή στήλης, η οποία μπορεί να σημαίνει απώλεια
δεδομένων. Για το λόγο αυτό, το σύστημα ζητά επιβεβαίωση, με ένα pop-up παράθυρο.
1.3 Διαγραφή πινάκων
Αν θέλουμε να διαγράψουμε από τη βάση μας έναν ολόκληρο πίνακα, η SQL εντολή που θα
χρησιμοποιήσουμε είναι η DROP η οποία συντάσσεται ως:
DROP TABLE <όνομα πίνακα>;
Και εδώ το σύστημα ζητάει επιβεβαίωση, όπως και στην DROP COLUMN.

Γράψτε την εντολή για την εισαγωγή μίας νέας στήλης με όνομα «GENRE» (είδος
ταινίας) και τύπο varchar(20) στον πίνακα MOVIES:

2 Χειρισμός Δεδομένων
Στην ενότητα αυτή θα δούμε πώς μπορούμε να εισάγουμε, να δούμε και να
τροποποιήσουμε δεδομένα στους πίνακες της βάσης μας.
2.1 Εισαγωγή δεδομένων
Για να εισάγουμε δεδομένα σε πίνακες χρησιμοποιούμε την εντολή INSERT. Η σύνταξή της
είναι η εξής:

INSERT INTO <όνομα πίνακα> VALUES (<λίστα τιμών>);

| Χειρισμός Δεδομένων 5
[Type text]

Η λίστα τιμών περιλαμβάνει μία τιμή για κάθε πεδίο του πίνακα στον οποίο θα γίνει η
εισαγωγή. Για παράδειγμα, αν θέλουμε να εισάγουμε μία πλειάδα στον πίνακα ACTORS θα
πρέπει να δώσουμε μία συγκεκριμένη τιμή για το πεδίο ID, μία για το NAME, μία για το
BIRTHDATE κ.ο.κ. Αν σε κάποιο πεδίο δεν θέλουμε να δώσουμε τιμή, τότε αναγράφουμε
την λέξη NULL. Π.χ.:

INSERT INTO ACTORS VALUES (‘A01’, ‘Brad Pitt’, ’1963-12-18’,


‘Oklahoma’, NULL);

Παρατηρήστε ότι οι τιμές που αντιστοιχούν σε πεδία τύπου varchar και date περικλείονται
μέσα σε μονά εισαγωγικά (όχι διπλά – είναι λάθος) ενώ οι τιμές που αντιστοιχούν σε
αριθμητικά πεδία (int, real κτλ) όχι.
Προσοχή στις τιμές NULL: αυτή σημαίνει ότι θέλουμε η θέση αυτή να μείνει κενή. Για το
λόγο αυτό, η λέξη δεν μπαίνει σε εισαγωγικά, γιατί τότε θα αποθηκευθεί η σειρά
χαρακτήρων ‘NULL’, και η αντίστοιχη θέση ΔΕΝ θα μείνει κενή.
Γενική παρατήρηση: στην SQL, το διαχωριστικό για αντικείμενα που σχηματίζουν λίστα
οποιασδήποτε μορφής είναι το κόμμα (,).
Κάθε εντολή INSERT μπορεί να εισάγει μία και μόνο πλειάδα (δηλ. γραμμή) σε έναν και
μόνο πίνακα. Αν θέλουμε να εισάγουμε πολλές πλειάδες πρέπει να εκτελέσουμε πολλές
εντολές INSERT.
Αν θέλουμε να εισάγουμε τιμές σε μερικά μόνο πεδία του πίνακα και όχι σε όλα, τότε
μπορούμε να χρησιμοποιήσουμε την παρακάτω μορφή της εντολής INSERT:
INSERT INTO <όνομα πίνακα> (<λίστα πεδίων>) VALUES (<λίστα
τιμών>);
Για παράδειγμα:
INSERT INTO ACTORS (ID, ΝΑΜΕ) VALUES (‘A02’, ‘George Clooney’);
Όταν χρησιμοποιούμε αυτήν την μορφή της εντολής, τα πεδία για τα οποία δεν
προσδιορίζουμε κάποια τιμή παίρνουν αυτόματα την ειδική «τιμή» NULL (δηλαδή το
αντίστοιχο πεδίο μένει κενό). Προφανώς στην περίπτωση αυτή, πρέπει να δώσουμε τιμή
τουλάχιστον σε όλα τα NOT NULL πεδία. Σε αυτά περιλαμβάνεται πάντα και το πρωτεύον
κλειδί, τα χαρακτηριστικά του οποίου δεν επιτρέπεται να πάρουν την «τιμή» NULL, δηλαδή
να μείνουν κενά.
2.2 Επισκόπηση δεδομένων
Για να δούμε τα περιεχόμενα ενός πίνακα χρησιμοποιούμε την εντολή SELECT. Η εντολή
αυτή μπορεί να έχει πολλές μορφές που θα δούμε σιγά-σιγά κατά τη διάρκεια του
μαθήματος. Η πιο απλή μορφή της, με την οποία μπορούμε να δούμε τα δεδομένα ενός
πίνακα, είναι η εξής:
SELECT *
FROM <όνομα πίνακα>;
Για παράδειγμα:
SELECT *
FROM ACTORS;

6 Χειρισμός Δεδομένων |
Το * σημαίνει ότι θέλουμε να δούμε για κάθε πλειάδα τις τιμές όλων των πεδίων του
πίνακα. Αν δεν μας ενδιαφέρουν όλα τα πεδία αλλά μόνο κάποια από αυτά μπορούμε να τα
προσδιορίσουμε ως εξής:
SELECT <λίστα πεδίων>
FROM <όνομα πίνακα>;
Για παράδειγμα:
SELECT NAME, OSCARS
FROM ACTORS;
Εδώ μπορούμε να περιλάβουμε και εκφράσεις που περιέχουν υπολογισμούς. Για
παράδειγμα, η εντολή
SELECT TITLE, BUDGET * 1.1
FROM MOVIES;
δείχνει τους τίτλους των ταινιών και τους αντίστοιχους προϋπολογισμούς, αυξημένους
όμως κατά 10%.
2.3 Τροποποίηση δεδομένων
Στους πίνακές μας υπάρχουν πλέον κάποια δεδομένα. Για την τροποποίηση των δεδομένων
των πινάκων μας υπάρχουν οι εντολές UPDATE, η οποία τροποποιεί πλειάδες που ήδη
υπάρχουν σε έναν πίνακα (σε αντίθεση με την INSERT η οποία δημιουργεί καινούριες
πλειάδες), καθώς και η εντολή DELETE, η οποία διαγράφει πλειάδες.

2.3.1 Τροποποίηση πλειάδων


Η σύνταξη της εντολής UPDATE είναι η εξής:
UPDATE <όνομα πίνακα>
SET <όνομα πεδίου> = <νέα τιμή>
WHERE <συνθήκη>;
Στο κομμάτι SET της εντολής λέμε τι αλλαγή θέλουμε να κάνουμε και στο κομμάτι WHERE
λέμε σε ποια (ή ποιες) πλειάδες θέλουμε να εφαρμοστεί η αλλαγή.
Για παράδειγμα, αν θέλουμε να τροποποιήσουμε την ημερομηνία γέννησης του ηθοποιού
με αριθμό ταυτότητας A02 και να την κάνουμε ίση με 15 Αυγούστου 1968, η εντολή που
πρέπει να εκτελέσουμε είναι:
UPDATE ACTORS
SET BIRTHDATE = ‘1968-08-15’
WHERE ID = ‘A02’;

Αν θέλαμε να αυξήσουμε τον αριθμό εισιτηρίων της ταινίας με τίτλο AVATAR κατά 100.000,
θα εκτελούσαμε την εντολή:
UPDATE MOVIES
SET TICKETS = TICKETS + 100000
WHERE TITLE = ‘AVATAR’;

| Χειρισμός Δεδομένων 7
[Type text]

Στο παραπάνω παράδειγμα βλέπουμε πως στο κομμάτι SET της εντολής μπορούμε να
εκτελούμε και απλές αριθμητικές πράξεις (όταν βέβαια τροποποιούμε αριθμητικά πεδία
και όχι συμβολοσειρές). Τέτοιες πράξεις είναι η πρόσθεση (+), η αφαίρεση (-), ο
πολλαπλασιασμός (*) και η διαίρεση (/). Θα πρέπει επίσης να λάβουμε υπόψη ότι για να
τροποποιηθεί στο συγκεκριμένο παράδειγμα ο αριθμός των εισιτηρίων θα πρέπει να
υπάρχει η ταινία με τίτλο AVATAR και ότι τα κεφαλαία γράμματα διαφέρουν από τα μικρά
όταν δίνονται ως τιμές πεδίων. Η εντολή δηλαδή θα τροποποιήσει μόνο τις πλειάδες με
τιμή ‘AVATAR’ στο πεδίο TITLE και όχι τις πλειάδες με τιμή ‘avatar’ ή ‘Avatar’.
Για να μειώσουμε το κόστος όλων των ταινιών κατά 10% μπορούμε να γράψουμε:
UPDATE MOVIES
SET BUDGET = 0.9 * BUDGET;
Αν από την εντολή UPDATE παραλείψουμε εντελώς το κομμάτι WHERE (που καθορίζει τις
πλειάδες στις οποίες θα εφαρμοστεί η τροποποίηση), τότε η τροποποίηση θα εφαρμοστεί
σε όλες τις πλειάδες του πίνακα, όπως στο παραπάνω παράδειγμα.
Πρέπει να είμαστε ιδιαίτερα προσεκτικοί με τη σύνταξη της εντολής μας γιατί οι
τροποποιήσεις που κάνουμε δεν μπορούν να αναιρεθούν! Επομένως, αν τροποποιήσουμε
όλες τις πλειάδες του πίνακα αντί για την μία που θέλαμε, δεν μπορούμε να επαναφέρουμε
τον πίνακα στην αρχική του μορφή.

Δημιουργείστε μία νέα πλειάδα στη βάση σας για την ηθοποιό Nicole Kidman που
γεννήθηκε στις 20 Ιουνίου 1967. Ο αριθμός ταυτότητάς της είναι Α03. Στη συνέχεια,
τροποποιήστε την πλειάδα ώστε να καταχωρηθεί στη βάση η πληροφορία ότι η
συγκεκριμένη ηθοποιός έχει κερδίσει 1 βραβείο oscar.

Αυξήστε κατά 20% τα κόστη όλων των ταινιών με σκηνοθέτη τον Steven Spielberg.

8 Χειρισμός Δεδομένων |
2.3.2 Διαγραφή πλειάδων
Η εντολή DELETE λειτουργεί με εντελώς αντίστοιχο τρόπο. Απουσιάζει φυσικά το κομμάτι
SET. Επομένως, η σύνταξή της είναι:
DELETE FROM <όνομα πίνακα>
WHERE <συνθήκη>;
Με την εκτέλεση της εντολής αυτής, διαγράφονται όσες πλειάδες του πίνακα ικανοποιούν
τη συνθήκη που ορίζεται στο κομμάτι WHERE.
Για παράδειγμα, αν θέλουμε να διαγράψουμε όλες τις ταινίες με έτος παραγωγής πριν το
1960, θα εκτελέσουμε την εντολή:
DELETE FROM MOVIES
WHERE YEAR <= 1960;
Όπως και στην περίπτωση της UPDATE, αν παραλείψουμε το κομμάτι WHERE, οι
τροποποιήσεις γίνονται σε όλες τις γραμμές του πίνακα. Επομένως, η εντολή:
DELETE MOVIES;
θα σβήσει όλες τις πλειάδες του πίνακα! Ο πίνακας θα συνεχίσει να υπάρχει στη βάση μας,
αλλά θα είναι πλέον άδειος, δηλαδή δεν θα έχει μέσα κανένα δεδομένο.
Και στην πρείπτωση αυτή, η εντολή ζητάει επιβεβαίωση πριν τη διαγραφή, ώστε να
αποφευχθεί κάποια ανεπιθύμητη απώλεια δεδομένων.

2.3.3 Αποθήκευση αλλαγών


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

COMMIT;

3 Σύνδεση πινάκων – Ξένα κλειδιά


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

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

| Σύνδεση πινάκων – Ξένα κλειδιά 9


[Type text]

θα συμμετέχουν στην συσχέτιση; Και με ποιες ακριβώς πλειάδες του MOVIES θα σχετίζεται
η κάθε μία;

Σε αυτό το σημείο πρέπει να θυμηθούμε την έννοια του πρωτεύοντος κλειδιού:

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

Επομένως, όταν θέλουμε να συσχετίσουμε έναν συγκεκριμένο ηθοποιό με μία


συγκεκριμένη ταινία, τα μόνα που χρειαζόμαστε είναι η τιμή του πρωτεύοντος κλειδιού του
πίνακα ACTORS για τον συγκεκριμένο ηθοποιό (δηλ. το ID) και η τιμή του πρωτεύοντος
κλειδιού του πίνακα MOVIES για τη συγκεκριμένη ταινία (δηλ. το TITLE).
Άρα, στον καινούριο μας πίνακα θα έχουμε ένα πεδίο για τον αριθμό ταυτότητας του
ηθοποιού και ένα πεδίο για τον τίτλο της ταινίας. Επίσης, σε κάθε δυάδα ηθοποιού-ταινίας
αντιστοιχεί ένα όνομα ρόλου και ένα ποσό με το οποίο αμείφθηκε ο ηθοποιός για το
συγκεκριμένο ρόλο. Ας επιλέξουμε λοιπόν ένα όνομα για τον νέο μας πίνακα και ονόματα
για τα τέσσερα πεδία του:

STARS
ID αριθμός ταυτότητας ηθοποιού
TITLE τίτλος ταινίας
ROLE όνομα ρόλου
CACHE ποσό αμοιβής

Στον πίνακα αυτό, υπάρχει μία ουσιώδης διαφορά από τους πίνακες που έχουμε δει έως
τώρα. Σε μερικά πεδία του πίνακα δεν μπορεί να εισαχθεί οποιαδήποτε τιμή. Κάθε τιμή του
πεδίου ID για παράδειγμα πρέπει να αντιστοιχεί σε κάποιο ID ενός ηθοποιού που
εμφανίζεται και στον πίνακα ACTORS. Αλλιώς θα είχαμε κάποιον που πρωταγωνιστεί σε
ταινία χωρίς να είναι ηθοποιός! Παρόμοια, κάθε τίτλος ταινίας που εμφανίζεται στον
πίνακα STARS πρέπει να εμφανίζεται ήδη και στον πίνακα MOVIES. Αυτή ακριβώς η
απαίτηση οδηγεί στον ορισμό ενός νέου είδους κλειδιού, του ξένου κλειδιού:

Ένα σύνολο από πεδία ενός πίνακα Α, έστω SΑ, είναι ξένο κλειδί προς ένα σύνολο από
πεδία του πίνακα Β, έστω SΒ, αν οι τιμές των πεδίων του SΑ σε κάθε πλειάδα tΑ του Α
- είτε εμφανίζονται αυτούσιες ως τιμές των πεδίων του SΒ σε κάποια πλειάδα tΒ του Β
- είτε είναι ίσες με NULL.

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

10 Σύνδεση πινάκων – Ξένα κλειδιά |


ότι ένα πεδίο είναι ξένο κλειδί, τότε κάθε τιμή που εισάγουμε σε αυτό πρέπει να υπάρχει
ήδη και στην αντίστοιχη στήλη του άλλου πίνακα.
Για να δημιουργήσουμε ξένα κλειδιά, προσθέτουμε στην εντολή CREATE TABLE γραμμές της
μορφής:
foreign key (<γνώρισμα ξένο-κλειδί>) references <όνομα πίνακα που
αναφερόμαστε>(<γνώρισμα στο οποίο αναφερόμαστε>)
Αν το <γνώρισμα ξένο-κλειδί> έχει το ίδιο όνομα με το <γνώρισμα στο οποίο
αναφερόμαστε>, τότε το δεύτερο μπορεί να παραλειφθεί. Επίσης, πρέπει να προσέχουμε
ώστε τα δύο αυτά πεδία να είναι του ίδιου τύπου. Για παράδειγμα, ένα πεδίο τύπου int δεν
μπορεί να είναι ξένο κλειδί σε ένα πεδίο τύπου varchar(20), επειδή τότε (προφανώς) δεν
μπορεί να υπάρξει αντιστοιχία τιμών.
Στο παράδειγμά μας λοιπόν θα είχαμε:
foreign key (ID) references ACTORS(ID),
foreign key (TITLE) references MOVIES(TITLE)

ή ισοδύναμα:
foreign key (ID) references ACTORS,
foreign key (TITLE) references MOVIES

Επομένως, η ολοκληρωμένη CREATE TABLE εντολή είναι:


CREATE TABLE STARS (
ID varchar(10),
TITLE varchar(50),
ROLE varchar(30),
CACHE real,
primary key (ID, TITLE),
foreign key (ID) references ACTORS,
foreign key (TITLE) references MOVIES
);

Τι θα άλλαζε στον πίνακα STARS αν υποθέταμε ότι κάθε ηθοποιούς μπορεί να κατέχει
πάνω από έναν πρωταγωνιστικούς ρόλους σε μία ταινία;

| Σύνδεση πινάκων – Ξένα κλειδιά 11


[Type text]

4 Η εντολή SELECT
Η εντολή SELECT είναι η σημαντικότερη εντολή της γλώσσας SQL. Μπορούμε να την
χρησιμοποιήσουμε για να δούμε τα δεδομένα που είναι αποθηκευμένα στην βάση μας και
για να τα συνδυάσουμε με διάφορους τρόπους μεταξύ τους ώστε να εξάγουμε την
πληροφορία που θέλουμε.
4.1 Ερωτήσεις SELECT με έναν πίνακα
Για να δούμε συγκεκριμένα δεδομένα που είναι αποθηκευμένα στη βάση μας,
υποβάλλουμε στη βάση μας ένα ερώτημα (query). Το βασικό εργαλείο για το σχηματισμό
ερωτημάτων είναι η εντολή SELECT. Κάθε εντολή SELECT αποτελείται από διάφορα δομικά
τμήματα τα οποία θα δούμε στη συνέχεια. Η πιο βασική μορφή της είναι η εξής:

SELECT <λίστα πεδίων>


FROM <λίστα πινάκων>
WHERE <συνθήκη>;
Στο κομμάτι SELECT βάζουμε τα πεδία που θέλουμε να εμφανίζονται στο αποτέλεσμα της
εντολής (ή ερώτησης). Στο FROM βάζουμε τους πίνακες που περιέχουν τα δεδομένα που θα
χρειαστούν στον υπολογισμό του ερωτήματος. Τέλος, στο WHERE βάζουμε συνθήκες που
πρέπει να πληρούν όλες οι πλειάδες που θα εμφανιστούν στο αποτέλεσμα. Αν δεν
απαιτείται κάποια ιδιαίτερη συνθήκη, τότε μπορεί να παραλειφθεί και το ερώτημα θα
αφορά ολόκληρο τον πίνακα.
Για παράδειγμα, η ερώτηση:
SELECT ID, NAME, BIRTHDATE
FROM ACTORS
WHERE BIRTHDATE > ’1950-01-01’;

θα εμφανίσει στη οθόνη τους αριθμούς ταυτότητας, τα ονόματα και τις ημερομηνίες
γέννησης μόνο για τους ηθοποιούς που έχουν γεννηθεί μετά την 1η Ιανουαρίου 1950. Όλοι
οι υπόλοιποι ηθοποιοί που βρίσκονται αποθηκευμένοι στον πίνακα ACTORS αλλά δεν έχουν
γεννηθεί μετά την 1η Ιανουαρίου 1950, δεν θα συμπεριληφθούν στο αποτέλεσμα της
SELECT ερώτησης.
Πρέπει να προσέχουμε ώστε στο FROM να χρησιμοποιούμε τους σωστούς πίνακες για την
κάθε μας ερώτηση. Για παράδειγμα, για να εμφανίσουμε τους αριθμούς ταυτότητας των
ηθοποιών που έχουν πρωταγωνιστήσει σε κάποια ταινία, η σωστή εντολή SELECT είναι:
SELECT ID
FROM STARS;

Γιατί δεν χρησιμοποιούμε τον πίνακα ACTORS στην παραπάνω ερώτηση;

12 Η εντολή SELECT |
Για να εμφανίσουμε τους αριθμούς ταυτότητας όλων των ηθοποιών που έχουν
πρωταγωνιστήσει στην ταινία με τίτλο TITANIC, γράφουμε:
SELECT ID
FROM STARS
WHERE TITLE = ‘TITANIC’;

4.1.1 Σύνθετες συνθήκες


Στο WHERE μπορεί να έχουμε σύνθετες συνθήκες, δηλαδή πολλές συνθήκες που
συνδέονται με λογικούς τελεστές. Υπάρχουν τρεις λογικοί τελεστές:
 AND: Το λογικό «και» (ή αλλιώς «τομή»)
 OR: Το λογικό «ή» (ή αλλιώς «ένωση»)
 NOT: Η λογική άρνηση (ή αλλιώς «συμπλήρωμα»)
Για παράδειγμα, για να εμφανίσουμε τους τίτλους των ταινιών που κυκλοφόρησαν το 2009
ή το 2011, λέμε:
SELECT TITLE
FROM MOVIES
WHERE YEAR = 2009 OR YEAR = 2011;

Για να εμφανίσουμε τους τίτλους και τον αριθμό των εισιτηρίων των ταινιών που
κυκλοφόρησαν το 2009 ή το 2011 και έχουν κόστος πάνω από €10.000.000, λέμε:
SELECT TITLE, TICKETS
FROM MOVIES
WHERE (YEAR = 2009 OR YEAR = 2011) AND BUDGET > 10000000;

Η σειρά προτεραιότητας των τελεστών είναι NOT, AND και τελευταίος ο OR. Μπορούμε να
χρησιμοποιούμε παρενθέσεις όπως στο παραπάνω παράδειγμα για να ορίζουμε τη σειρά
με την οποία θα αποτιμηθούν οι συνθήκες του WHERE.

Τι θα συνέβαινε αν δεν χρησιμοποιούσαμε τις παρενθέσεις στο παραπάνω


παράδειγμα;

4.1.2 Πράξεις
Μπορούμε επίσης να κάνουμε απλές αριθμητικές πράξεις στο SELECT. Για να δούμε π.χ. το
κόστος όλων των ταινιών με σκηνοθέτη τον Steven Spielberg διπλασιασμένο, λέμε:

| Η εντολή SELECT 13
[Type text]

SELECT TITLE, 2 * BUDGET


FROM MOVIES
WHERE DIRECTOR = ‘Steven Spielberg’;

4.1.3 Ο τελεστής LIKE


Υπάρχουν περιπτώσεις στις οποίες χρειάζεται να βρούμε πεδία που έχουν παρόμοιες τιμές
και όχι ακριβώς ίσες. Για τέτοιες περιπτώσεις υπάρχει ο τελεστής LIKE. Συντάσσεται ως
εξής:

SELECT TITLE, BUDGET


FROM MOVIES
WHERE DIRECTOR LIKE ‘%Spielberg%’;

Το σύμβολο «%» στην παραπάνω ερώτηση σημαίνει «οτιδήποτε». Δηλαδή, ουσιαστικά η


συνθήκη μας λέει «κράτησε μόνο τις πλειάδες που στο πεδίο DIRECTOR έχουν τιμή που
περιέχει την συμβολοσειρά ‘Spielberg’». Έτσι, στο αποτέλεσμα της συγκεκριμένης
ερώτησης θα συμπεριληφθούν όλες οι ταινίες που στο πεδίο DIRECTOR έχουν τιμές όπως
‘St. Spielberg’, ‘Spielberg’, ‘Spielberg Steven’ και όχι μόνο την τιμή ‘Steven Spielberg’ όπως
ισχύει με τον τελεστή «=».

Εμφανίστε τους τίτλους των ταινιών που κυκλοφόρησαν το 2011 και ο τίτλος τους
αρχίζει από «Α»:

4.1.4 Η μεταβλητή SYSDATE


H SYSDATE είναι μία ειδική μεταβλητή της βάσης μας που είναι τύπου date και περιέχει την
τρέχουσα ημερομηνία. Είναι χρήσιμη όταν θέλουμε να κάνουμε ερωτήσεις που εξαρτώνται
από την σημερινή ημερομηνία. Χρησιμοποιείται ως εξής:
SELECT *
FROM ACTORS
WHERE BIRTHDATE < SYSDATE;
4.1.5 Αλλαγή ονομάτων στηλών του αποτελέσματος
Υπάρχει η δυνατότητα, αν θέλουμε, να μετονομάσουμε τα ονόματα των στηλών του
αποτελέσματος ως εξής:

14 Η εντολή SELECT |
SELECT ID “Ar. Tautotitas”, NAME “Onoma”, BIRTHPLACE “Katagwgi”
FROM ACTORS
WHERE BIRTHPLACE LIKE ‘%USA%’;

Προσέξτε ότι στα νέα ονόματα των στηλών βάζουμε διπλά εισαγωγικά (είναι μία από τις
πολύ λίγες περιπτώσεις που στην SQL χρησιμοποιούνται διπλά αντί μονά εισαγωγικά). Η
παραπάνω ερώτηση δεν τροποποιεί τα ονόματα των πεδίων στον πίνακα. Τα ονόματα που
δώσαμε θα χρησιμοποιηθούν μία και μόνο φορά όταν θα μας εμφανιστεί το αποτέλεσμα
της συγκεκριμένης ερώτησης στην οθόνη.
4.1.6 Ταξινόμηση αποτελέσματος – ORDER BY
Πολλές φορές θέλουμε οι πλειάδες του αποτελέσματος της ερώτησης να εμφανιστούν στην
οθόνη με κάποια συγκεκριμένη σειρά και όχι τυχαία. Για το λόγο αυτό υπάρχει ένα δομικό
τμήμα της εντολής SELECT που μπορούμε να χρησιμοποιήσουμε, το ORDER BY.
Συντάσσεται ως εξής:
SELECT <λίστα πεδίων>
FROM <λίστα πινάκων>
WHERE <συνθήκη>
ORDER BY <λίστα πεδίων>;

H <λίστα πεδίων> του ORDER BY καθορίζει τα πεδία βάσει των οποίων γίνεται η ταξινόμηση
του αποτελέσματος. Για παράδειγμα, για να εμφανίσουμε όλους τους ηθοποιούς
ταξινομημένους κατά αλφαβητική σειρά, γράφουμε:
SELECT *
FROM ACTORS
ORDER BY NAME ASC;

Το ASC σημαίνει «αύξουσα ταξινόμηση» και μπορεί να παραλειφθεί (δηλαδή αν δεν


βάλουμε τίποτα εννοείται ότι είναι ASC).
Αν θέλουμε φθίνουσα ταξινόμηση, γράφουμε:
SELECT *
FROM ACTORS
ORDER BY NAME DESC;

Στο ORDER BY μπορούμε να έχουμε πολλά πεδία. Όταν γίνεται αυτό, οι πλειάδες πρώτα
ταξινομούνται με βάση το πρώτο μόνο πεδίο. Αν μερικές πλειάδες έχουν την ίδια τιμή σε
αυτό το πεδίο, τότε αυτές (και μόνο αυτές) ταξινομούνται με βάση το δεύτερο. Αν και σε
αυτό έχουν την ίδια τιμή, τότε ταξινομούνται με βάση το ίδιο πεδίο κ.ο.κ.
Για παράδειγμα, για να εμφανίσουμε τον τίτλο, το κόστος και το έτος παραγωγής όλων των
ταινιών με αύξουσα σειρά έτους παραγωγής και αλφαβητική σειρά τίτλου, λέμε:
SELECT TITLE, BUDGET, YEAR
FROM MOVIES

| Η εντολή SELECT 15
[Type text]

ORDER BY YEAR ASC, TITLE ASC;

Επίσης μπορούμε να έχουμε συνδυασμούς όπως:


SELECT TITLE, BUDGET, YEAR
FROM MOVIES
ORDER BY YEAR DESC, TITLE ASC;

4.1.7 Ο τελεστής ΙΝ
Ο τελεστής ΙΝ χρησιμοποιείται για να δείξουμε κάποιο σύνολο. Για παράδειγμα, η
παρακάτω ερώτηση θα εμφανίσει στοιχεία για τους ηθοποιούς που το όνομά τους είναι
(ακριβώς) είτε «Brad» είτε «Angelina».
SELECT *
FROM ACTORS
WHERE NAME IN (‘Brad’, ‘Angelina’);
4.1.8 Ο τελεστής BETWEEN
Εναλλακτικά, όταν έχουμε αριθμητικά ή date πεδία, αντί για μία συνθήκη της μορφής:
WHERE YEAR >=1990 AND YEAR <=2000
η οποία δίνει τις τιμές που βρίσκονται ανάμεσα στις δύο τιμές που μας ενδιαφέρουν,
μπορούμε ισοδύναμα να γράψουμε:
WHERE YEAR BETWEEN 1990 AND 2000

4.1.9 Εμφωλευμένες ερωτήσεις


Μία εμφωλευμένη ερώτηση έχει τη μορφή μίας κοινής SELECT ερώτησης η οποία
χρησιμοποιείται σε κάποιο σημείο μίας άλλης SELECT ερώτησης, συνήθως στο κομμάτι
WHERE. Υπάρχουν συγκεκριμένοι τελεστές που χρησιμοποιούνται για τη σύνταξη μιας
εμφωλευμένης ερώτησης:
Τελεστής ΙΝ:
Ο τελεστής IN χρησιμοποιείται για να ελεγχθεί αν οι τιμές ενός πεδίου ανήκουν στο
αποτέλεσμα που προκύπτει από μία εμφωλευμένη SELECT υπο-ερώτηση.
Για παράδειγμα, η ερώτηση
SELECT ID, NAME
FROM ACTORS
WHERE ID IN (SELECT ID
FROM STARS
WHERE TITLE = ‘The King’s Speech’);

θα εμφανίσει τους αριθμούς ταυτότητας και τα ονόματα των ηθοποιών που έχουν
πρωταγωνιστήσει στην ταινία The King’s Speech. Με την εμφωλευμένη SELECT βρίσκουμε
τους κωδικούς των ηθοποιών από την ταινία και ακολούθως με αυτούς τους κωδικούς
βρίσκουμε με την αρχική SELECT από τον πίνακα ACTORS και τα ονόματα τους.

16 Η εντολή SELECT |
Τελεστής SOME:
Ο τελεστής SOME χρησιμοποιείται για να συγκρίνουμε τις τιμές ενός πεδίου με τις τιμές του
αποτελέσματος που προκύπτει από μία εμφωλευμένη SELECT υπο-ερώτηση. Ο τελεστής
SOME χρησιμοποιείται μαζί με κάποιον από τους τελεστές σύγκρισης >, <, =, >=, <=, <> και
ελέγχει αν η τιμή ενός πεδίου είναι μεγαλύτερη/μικρότερη/ίση/μεγαλύτερη ή
ίση/μικρότερη ή ίση/διάφορη αντίστοιχα από κάποια (μία τουλάχιστον) τιμή του
αποτελέσματος της εμφωλευμένης υπο-ερώτησης.
Για παράδειγμα, αν θέλουμε να εμφανίσουμε τους τίτλους και το έτος παραγωγής των
ταινιών οι οποίες κόστισαν περισσότερο από κάποια (οποιαδήποτε) ταινία που έχει
σκηνοθετήσει ο Steven Spielberg, η εντολή είναι:
SELECT TITLE, YEAR
FROM MOVIES
WHERE BUDGET > SOME (SELECT BUDGET
FROM MOVIES
WHERE DIRECTOR= ‘Steven Spielberg’);

Είναι αυτονόητο ότι, τόσο στην περίπτωση του SOME όσο και του IN, πρέπει να
φροντίσουμε ώστε οι δύο πλευρές της σύγκρισης να είναι συμβατές μεταξύ τους.

Εμφανίστε τους αριθμούς ταυτότητας των ηθοποιών που έχουν συμπρωταγωνιστήσει


σε μία τουλάχιστον ταινία με τον ηθοποιό που έχει αριθμό ταυτότητας GT0102.

Τελεστής ALL:
Ο τελεστής ALL χρησιμοποιείται για να συγκρίνουμε τις τιμές ενός πεδίου με όλες τις τιμές
του αποτελέσματος που προκύπτει από μία εμφωλευμένη SELECT υπο-ερώτηση. Ο
τελεστής ALL χρησιμοποιείται μαζί με κάποιον από τους τελεστές σύγκρισης >, <, =, >=, <=,
<> και ελέγχει αν η τιμή ενός πεδίου είναι μεγαλύτερη/μικρότερη/ίση/μεγαλύτερη ή
ίση/μικρότερη ή ίση/διάφορη αντίστοιχα από όλες τις τιμές του αποτελέσματος της
εμφωλευμένης υπο-ερώτησης.
Για παράδειγμα, αν θέλουμε να εμφανίσουμε τους τίτλους και το έτος παραγωγής των
ταινιών οι οποίες κόστισαν περισσότερο από κάθε ταινία (δηλαδή όλες) που κυκλοφόρησε
το 2011, η εντολή είναι:
SELECT TITLE, YEAR
FROM MOVIES

| Η εντολή SELECT 17
[Type text]

WHERE BUDGET > ALL (SELECT BUDGET


FROM MOVIES
WHERE YEAR = 2011);

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

Εμφανίστε τους αριθμούς ταυτότητας των ηθοποιών που δεν έχουν πρωταγωνιστήσει
σε καμία ταινία με σκηνοθέτη τον James Cameron.

4.2 Πράξεις μεταξύ SELECT ερωτήσεων


Μεταξύ των αποτελεσμάτων δύο SELECT ερωτήσεων ορίζονται οι πράξεις τις ένωσης, της
τομής και της διαφοράς (ή εξαίρεσης). Αυτές οι πράξεις έχουν την έννοια που έχουν και στις
πράξεις μεταξύ συνόλων, τις ,  και – αντίστοιχα. Έτσι, μπορούμε να συνδέσουμε δύο
SELECT ερωτήσεις για να πάρουμε σαν τελικό αποτέλεσμα την ένωση, την τομή ή την
διαφορά αντίστοιχα των δύο αποτελεσμάτων, αρκεί τα αποτελέσματα των δύο ερωτήσεων
να περιέχουν τις ίδιες στήλες (να υπάρχουν τα ίδια πεδία στο SELECT κομμάτι των
ερωτήσεων) και αυτές να έχουν τον ίδιο τύπο δεδομένων.
4.2.1 Ένωση SELECT ερωτήσεων
Ο τελεστής UNION μεταξύ δύο SELECT ερωτήσεων μας δίνει σαν αποτέλεσμα όλες τις
πλειάδες που ανήκουν στο αποτέλεσμα μίας τουλάχιστον εκ των δύο SELECT ερωτήσεων.
Συνεπώς, αν για παράδειγμα θέλουμε να βρούμε όλους τους αριθμούς ταυτότητας των
ηθοποιών που έχουν κερδίσει περισσότερα από 2 oscar ή έχουν αμειφθεί με περισσότερα
από €10.000.000 για κάποιον ρόλο τους, ένας τρόπος είναι να γράψουμε:
(SELECT ID
FROM ACTORS
WHERE OSCARS > 2)
UNION
(SELECT ID
FROM STARS
WHERE CACHE > 10000000);
18 Η εντολή SELECT |
4.2.2 Τομή SELECT ερωτήσεων
Ο τελεστής INTERSECT μεταξύ δύο SELECT ερωτήσεων μας δίνει σαν αποτέλεσμα όλες τις
πλειάδες που ανήκουν στο αποτέλεσμα και των δύο SELECT ερωτήσεων.
Συνεπώς, αν για παράδειγμα θέλουμε να βρούμε όλους τους αριθμούς ταυτότητας των
ηθοποιών που έχουν κερδίσει περισσότερα από 2 oscar και έχουν πρωταγωνιστήσει στην
ταινία Armagedon, γράφουμε:

(SELECT ID
FROM ACTORS
WHERE OSCARS > 2)
INTERSECT
(SELECT ID
FROM STARS
WHERE TITLE = ‘Armagedon);
4.2.3 Εξαίρεση SELECT ερωτήσεων
Ο τελεστής MINUS μεταξύ δύο SELECT ερωτήσεων μας δίνει σαν αποτέλεσμα όλες τις
πλειάδες που ανήκουν στο αποτέλεσμα της πρώτης αλλά όχι της δεύτερης εκ των δύο
SELECT ερωτήσεων.
Συνεπώς, αν για παράδειγμα θέλουμε να βρούμε όλους τους αριθμούς ταυτότητας των
ηθοποιών που έχουν κερδίσει περισσότερα από 2 oscar αλλά δεν έχουν πρωταγωνιστήσει
στην ταινία Armagedon, γράφουμε:
(SELECT ID
FROM ACTORS
WHERE OSCARS > 2)
MINUS
(SELECT ID
FROM STARS
WHERE TITLE = ‘Armagedon’);

4.3 Ερωτήσεις SELECT με πολλούς πίνακες


Θυμίζουμε το σχήμα της βάσης μας:

| Η εντολή SELECT 19
[Type text]

ACTORS
ID NAME BIRTHDATE BIRTHPLACE OSCARS
S

MOVIES
TITLE YEAR DIRECTOR BUDGET TICKETS

STARS
ID TITLE ROLE CACHE

Πολλές φορές τα δεδομένα που χρειαζόμαστε δεν είναι αποθηκευμένα σε έναν μόνο
πίνακα αλλά βρίσκονται διάσπαρτα στη βάση. Σε αυτήν την περίπτωση πρέπει να
συνδυάσουμε πολλούς πίνακες στην ερώτησή μας έτσι ώστε να εξάγουμε το επιθυμητό
αποτέλεσμα.
Όταν έχουμε σύνδεση (ή αλλιώς «join») πολλών πινάκων, τότε πρέπει να προσέχουμε δύο
πράγματα:
 Ποιους ακριβώς πίνακες χρειαζόμαστε ώστε να τους βάλουμε στο FROM
 Ποιες συνθήκες σύνδεσης χρειαζόμαστε ώστε να τις βάλουμε στο WHERE
Το πρώτο είναι απλό. Έστω για παράδειγμα ότι θέλουμε να βρούμε για κάθε ηθοποιό το
όνομά του και τον τίτλο των ταινιών που έχει πρωταγωνιστήσει. Από το σχήμα της βάσης
μας βλέπουμε ότι οι πίνακες που χρειαζόμαστε είναι ο ACTORS και ο STARS.
Έστω ότι κάποια στιγμή τα δεδομένα που υπάρχουν στη βάση μας είναι:

Δοκιμάζουμε την εντολή:

20 Η εντολή SELECT |
SELECT NAME, TITLE
FROM ACTORS, STARS;

Το αποτέλεσμα είναι:

Βλέπουμε δηλαδή πως όλες οι πλειάδες του ACTORS ενώνονται με όλες τις πλειάδες του
STARS! Ερμηνεύοντας τα αποτελέσματα του ερωτήματος θα βγάλουμε το συμπέρασμα πως
η Sandra Bullock έχει πρωταγωνιστήσει στο Inglourious Basterds και στο The Shawshank
Redemption. Κάτι τέτοιο είναι προφανώς λάθος!
Το παραπάνω παράδειγμα είναι το Καρτεσιανό Γινόμενο των δύο πινάκων, το οποίο
περιέχει όσα στοιχεία μας χρειάζονται πραγματικά, αλλά περιλαμβάνει και αρκετά που μας
είναι παντελώς άχρηστα και δεν έχουν νόημα.
Πρέπει λοιπόν να φροντίσουμε ώστε η εντολή μας να είναι ορθή, δηλαδή να συνδέει
μεταξύ τους πλειάδες των δύο πινάκων που αναφέρονται στον ίδιο ηθοποιό, δηλαδή:
SELECT NAME, TITLE
FROM ACTORS, STARS
WHERE [Link] = [Link];

Βλέπετε λοιπόν πως το ερώτημα σας πρέπει να είναι διατυπωμένο σωστά γιατί αλλιώς θα
εξάγετε λανθασμένα συμπεράσματα από το αποτέλεσμά του!
Αν θέλουμε επιπλέον να εμφανίσουμε το όνομα του σκηνοθέτη κάθε ταινίας στην οποία
πρωταγωνιστεί κάθε ηθοποιός, θα χρειαστούμε και τον πίνακα MOVIES:

SELECT [Link], [Link], [Link]


FROM ACTORS, STARS, MOVIES
WHERE [Link] = [Link] AND [Link] = [Link];

| Η εντολή SELECT 21
[Type text]

Εύκολα μπορεί κανείς να διαπιστώσει ότι η σύνδεση περιλαμβάνει ένα ξένο κλειδί από τον
ένα πίνακα και το πεδίο εκείνο από τον άλλο πίνακα, στο οποίο αναφέρεται αυτό το ξένο
κλειδί

Εμφανίστε τους αριθμούς ταυτότητας και τα ονόματα των ηθοποιών που έχουν
πρωταγωνιστήσει σε ταινία με σκηνοθέτη τον Stanley Kubrick.

4.4 Συναθροιστικές συναρτήσεις


Η SQL προσφέρει ένα σύνολο συναρτήσεων που μπορούν να εφαρμοστούν σε ένα σύνολο
πλειάδων και να υπολογίσουν μία αριθμητική τιμή από αυτό. Τέτοιες συναρτήσεις είναι:
 Το ελάχιστο (min)
 Το μέγιστο (max)
 Το άθροισμα (sum)
 Ο μέσος όρος (avg)
 Το πλήθος (count)
Όπως γίνεται αντιληπτό από τη φύση των συναρτήσεων αυτών, μπορούν να υπολογιστούν
μόνο βάσει των αριθμητικών ή date πεδίων των πλειάδων. Μόνη εξαίρεση είναι το count
που απλά μετράει το πλήθος των πλειάδων, οπότε σε αυτήν την περίπτωση δεν παίζει
κάποιο ρόλο το τι ακριβώς περιέχουν αυτές οι πλειάδες. Προσοχή: οι συναρτήσεις αυτές
δεν λαμβάνουν υπ’ όψη τους τις τιμές που είναι κενές.
Αν θέλουμε για παράδειγμα να βρούμε το μέσο όρο κόστους των ταινιών, μπορούμε να
πούμε:
SELECT avg(BUDGET)
FROM MOVIES;

Η συναθροιστική συνάρτηση βρίσκεται δηλαδή στο κομμάτι SELECT της εντολής και παίρνει
ως όρισμα το πεδίο πάνω στο οποίο θα εφαρμοστεί.
Αν θέλουμε να μετρήσουμε πόσοι είναι οι ηθοποιοί, λέμε:
SELECT count(*)
FROM ACTORS;

ή, ισοδύναμα:
22 Η εντολή SELECT |
SELECT count(ID) ή SELECT count(ΝΑΜΕ)
FROM ACTORS; FROM ACTORS;

Αν, όμως θέλουμε να μετρήσουμε το πόσοι είναι οι ηθοποιοί που πρωταγωνιστούν σε


κάποια ταινία, η ερώτηση
SELECT count(ID)
FROM STARS;

είναι λανθασμένη. Επειδή το ίδιο ID μπορεί να εμφανίζεται πολλές φορές στον STARS, θα
μετρήσουμε περισσότερους ηθοποιούς από όσους πρωταγωνιστούν πράγματι σε κάποια
ταινία. Την λύση προσφέρει η επιλογή DISTINCT (που σημαίνει «διακριτός»). Αν την
χρησιμοποιήσουμε τότε η count δεν μετράει τις διπλές εμφανίσεις:

SELECT count(DISTINCT ID)


FROM STARS;

Η συνάρτηση COUNT() χρειάζεται κάποια προσοχή. Επειδή όπως είπαμε παραπάνω οι


συναρτήσεις λαμβάνουν υπ’ όψη τους μόνο τις τιμές που δεν είναι NULL, πρέπει να
προσέχουμε ποιο χαρακτηριστικό θα ζητήσουμε να μετρηθεί με την εντολή μας. Για
παράδειγμα, αν θέλουμε να μετρήσουμε πόσοι ηθοποιοί είναι καταχωρημένοι, τότε οι
εντολές
SELECT count(ID)
FROM ACTORS;
και
SELECT count(*)
FROM ACTORS;
έχουν το ίδιο αποτέλεσμα, καθώς το πεδίο ID έχει πάντοτε μια τιμή, ως πρωτεύον κλειδί.
Αντίθετα, η εντολή
SELECT count(BIRTHDATE)
FROM ACTORS;
μπορεί να δώσει διαφορετικό αποτέλεσμα, αν για κάποιους ηθοποιούς δεν έχουμε
καταχωρήσει ημερομηνία γέννησης.

Βρείτε την μεγαλύτερη και την μικρότερη αμοιβή που έχει πάρει ποτέ ο ηθοποιός με
αριθμό ταυτότητας A08 για ρόλο που έχει παίξει.

| Η εντολή SELECT 23
[Type text]

4.4.1 Ομαδοποίηση
Στην πράξη σπάνια μας ενδιαφέρει να υπολογίσουμε μία συναθροιστική συνάρτηση
βασισμένη σε όλες τις πλειάδες ενός πίνακα. Συνήθως μας ενδιαφέρει μόνο ένα υποσύνολο
αυτών. Για παράδειγμα, πώς θα βρούμε το μέσο όρο αμοιβής των ηθοποιών ανά ταινία
(δηλαδή, ξεχωριστά το μέσο όρο για αυτούς που πρωταγωνιστούν στην ταινία Titanic,
ξεχωριστά το μέσο όρο για τους πρωταγωνιστές της ταινίας Armagedon κ.ο.κ);
Για να χωρίσουμε τις πλειάδες μας σε μικρότερες ομάδες, υπάρχει ένα άλλο δομικό
στοιχείο της εντολής SELECT, το κομμάτι GROUP BY. Συντάσσεται ως εξής:
SELECT <λίστα πεδίων>
FROM <λίστα πινάκων>
WHERE <συνθήκη>
GROYP BY <λίστα πεδίων>;

Αν στο GROUP BY έχουμε ένα και μόνο πεδίο, τότε οι πλειάδες μας χωρίζονται με βάση
αυτό. Για παράδειγμα, η εντολή:
SELECT TITLE, avg(CACHE)
FROM STARS
GROYP BY TITLE;

πρώτα χωρίζει τις πλειάδες του πίνακα STARS σε ομάδες ανάλογα με την τιμή τους στο
πεδίο TITLE (μία ομάδα για όλους τους πρωταγωνιστικούς ρόλους με τιμή στο TITLE ίση με
Titanic, μία για αυτούς με τιμή ίση με Armagedon κτλ.) και μετά εφαρμόζει την
συναθροιστική συνάρτηση σε κάθε ομάδα χωριστά. Αν δηλαδή υπάρχουν 5 διαφορετικές
ταινίες στον πίνακα STARS, τότε η παραπάνω ερώτηση θα δώσει 5 διαφορετικούς μέσους
όρους, έναν για κάθε ομάδα. Για να ξεχωρίζουμε ποια τιμή αντιστοιχεί σε κάθε ομάδα,
χρειάζεται στο SELECT να βάζουμε και το πεδίο που υπάρχει στο GROUP BY. Προσοχή: το
μόνο πεδίο που μπορεί να υπάρχει στη SELECT είναι το πεδίο με βάση το οποίο γίνεται η
ομαδοποίηση, και φυσικά και όποιες συναρτήσεις θέλουμε να υπολογισθούν.
Μπορούμε, αν θέλουμε, στο GROUP BY να έχουμε παραπάνω από ένα πεδία. Στην
περίπτωση αυτή, ο πίνακας πρώτα θα χωριστεί σε ομάδες με βάση το 1ο πεδίο και στη
συνέχεια κάθε ομάδα θα ξαναχωριστεί με βάση στο 2ο πεδίο κ.ο.κ. Οι συναθροιστικές
συναρτήσεις θα υπολογιστούν ξεχωριστά για κάθε μία από αυτές τις μικρότερες ομάδες
που προέκυψαν στο τέλος.

24 Η εντολή SELECT |
Ας δούμε μερικά παραδείγματα ομαδοποίησης:
Εμφάνιση του πλήθους των ταινιών με λιγότερα από 1.000.000 εισιτήρια ανά σκηνοθέτη :
SELECT DIRECTOR, COUNT(*)
FROM MOVIES
WHERE TICKETS < 1000000
GROUP BY DIRECTOR;

Εμφάνιση του πλήθους των πρωταγωνιστών ανά σκηνοθέτη και ανά ταινία:
SELECT DIRECTOR, [Link], COUNT(*)
FROM STARS, MOVIES
WHERE [Link] = [Link]
GROUP BY DIRECTOR, [Link];

Βρείτε για κάθε ταινία τον συνολικό αριθμό των oscars που έχουν κερδίσει οι
πρωταγωνιστές της:

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

| Η εντολή SELECT 25
[Type text]

Τέλος, σε κάποιες περιπτώσεις, μπορεί να μην θέλουμε να εμφανιστούν όλες οι ομάδες στο
αποτέλεσμα. Για να διαλέξουμε μόνο κάποιες από τις ομάδες, χρησιμοποιούμε ένα νέο το
κομμάτι της εντολής SELECT. Το κομμάτι αυτό είναι το HAVING. Συντάσσεται ως εξής:
SELECT <λίστα πεδίων>
FROM <λίστα πινάκων>
WHERE <συνθήκη>
GROYP BY <λίστα πεδίων>
HAVING <συνθήκη>;

Στο HAVING χρησιμοποιούμε συνθήκες που μπορούν να εφαρμοστούν σε μία ολόκληρη


ομάδα και όχι σε κάθε πλειάδα της ομάδας ξεχωριστά (αυτή άλλωστε είναι και η διαφορά
του με το WHERE).
Για παράδειγμα, αν θέλουμε να βρούμε τους αριθμούς ταυτότητας και τον αριθμό των
ταινιών στις οποίες έχει πρωταγωνιστήσει κάθε ηθοποιός, μόνο για τους ηθοποιούς που
έχουν πρωταγωνιστήσει σε περισσότερες από 15 ταινίες, γράφουμε:
SELECT ID, COUNT(*)
FROM STARS
GROYP BY ID
HAVING COUNT(*) > 15;

Για να εμφανίσουμε τον αριθμό ταινιών που έχει σκηνοθετήσει κάθε σκηνοθέτης, μόνο για
τους σκηνοθέτες οι οποίοι έχουν σκηνοθετήσει περισσότερες ταινίες από τον σκηνοθέτη
Kubrick, γράφουμε:
SELECT DIRECTOR, COUNT(*)
FROM MOVIES
GROYP BY DIRECTOR
HAVING COUNT(*) > (SELECT COUNT(*)
FROM MOVIES
WHERE DIRECTOR = ‘Kubrick’) ;

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

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

26 Η εντολή SELECT |
| Η εντολή SELECT 27

You might also like