3. 3
regnum name semester age
121 Steve A 33
145 Graham B 45
646 Yanis A 37
756 Pye B 28
913 Evi A 30
152 George B 33
123 David A 60
178 Paul B 28
199 Eve A 28
Για αρχή…
ελέγξτε αν ο πίνακας student έχει τα παρακάτω δεδομένα:
4. Αλλάξετε το όνομα του πεδίου regnum του πίνακα student σε sid.
alter table student change regnum sid int;
Δημιουργήστε ένα νέο πίνακα dept (did, name) με τα στοιχεία του τμήματος
που θα ανήκει κάθε σπουδαστής (κάθε σπουδαστής μπορεί να ανήκει μόνο
σε ένα τμήμα)
create table dept (did int primary key not null,
name varchar(40));
Εισάγετε στον πίνακα dept τις παρακάτω εγγραφές
4
did name
1 cs
2 ceng
3 physics
5. Πώς υλοποιούμε τη σχέση ότι ένας σπουδαστής ανήκει σε ένα τμήμα;
Είναι καλή λύση να προσθέσουμε στον πίνακα dept ένα πεδίο-πίνακα με τα sid
όλων των σπουδαστών του;
5
did name sid
1 cs 121, 123, 145, 152, 178, 199
2 ceng 646, 756, 913
3 physics
sid name semeste
r
age
121 Steve A 33
145 Graham B 45
646 Yanis A 37
756 Pye B 28
913 Evi A 30
152 George B 33
123 David A 60
178 Paul B 28
199 Eve A 28
did name
1 cs
2 ceng
3 physics
student
dept
dept
6. Προσθέσετε στον πίνακα student ένα πεδίο που θα δείχνει το τμήμα στο οποίο
ανήκει
alter table student add did int;
Ενημερώστε το νέο πεδίο ως εξής:
◦ 1 για μαθητές με sid<=200
◦ 2 για μαθητές με sid>200
update student set did = 1 where sid <= 200;
update student set did = 2 where sid > 200;
6
Σύνδεση πινάκων (3)Σύνδεση πινάκων (3)
7. Πώς θα απαντήσουμε το ερώτημα σε ποιό τμήμα ανήκει ο Steve?
Δοκιμάστε το query:
select *
from dept, student;
Το αποτέλεσμά του είναι το “γινόμενο” student * dept
7
did name
1 cs
2 ceng
3 physics
sid name semester age did
121 Steve A 33 1
145 Graham B 45 1
646 Yanis A 37 2
756 Pye B 28 2
913 Evi A 30 2
152 George B 33 1
123 David A 60 1
178 Paul B 28 1
199 Eve A 28 1
…
…
27 εγγραφές
8. Στη συνέχεια τρέξτε το:
select * συνθήκη σύνδεσης
from dept, student πίνακας1.πεδίο= πίνακας2.πεδίο
where dept.did = student.did;
Τι ακριβώς είναι το αποτέλεσμά του query;
8
sid name semester age did
121 Steve A 33 1
145 Graham B 45 1
646 Yanis A 37 2
756 Pye B 28 2
913 Evi A 30 2
152 George B 33 1
123 David A 60 1
178 Paul B 28 1
199 Eve A 28 1
did name
1 cs
2 ceng
3 physics
9 εγγραφές
9. Το inner join μπορεί να πραγματοποιηθεί με δύο τρόπους:
Σύνδεση στο WHERE
select *
from dept, student
where dept.did = student.did;
Σύνδεση στο FROM
select *
from dept inner join student on dept.did = student.did;
9
Join - inner join (3)Join - inner join (3)
10. Άσκηση: Να εμφανίσετε το όνομα του τμήματος στο οποίο
ανήκει ο Steve
select dept.name
from dept, student
where dept.did = student.did
and student.name = ‘Steve’;
ή
select dept.name
from dept inner join student on dept.did = student.did
where student.name = 'Steve';
10
Join - inner join (4)Join - inner join (4)
11. Πως θα απαντήσουμε στο query:
Ποιά τμήματα δεν έχουν κανένα σπουδαστή;
Μπορεί να απαντήσει το query
select *
from dept, student
where dept.did = student.did;
Όχι, γιατί εμφανίζει τις εγγραφές που έχουν στοιχεία και στους δύο πίνακες. Άρα
δεν εμφανίζει καθόλου τα τμήματα που δεν έχουν κανένα σπουδαστή.
Για να εμφανιστούν όλες οι εγγραφές (είτε έχουν αντίστοιχα στοιχεία και στους
δύο πίνακες είτε δεν έχουν) χρησιμοποιούμε το
outer join (εξωτερικές συνδέσεις)
left outer join
right outer join
full outer join (δεν υποστηρίζεται ακόμη από την mysql)
11
12. select *
from dept left outer join student on dept.did = student.did;
Το παραπάνω ερώτημα εμφανίζει όλες τις εγγραφές του αριστερού πίνακα
(δηλαδή του dept) ανεξάρτητα αν υπάρχει αντίστοιχη καταχώρηση στον δεξιό
πίνακα (στον student).
Στο αποτέλεσμα υπάρχει και μία επιπλέον εγγραφή:
3 physics NULL NULL NULL NULL NULL
12
sid name semester age did
121 Steve A 33 1
145 Graham B 45 1
646 Yanis A 37 2
756 Pye B 28 2
913 Evi A 30 2
152 George B 33 1
123 David A 60 1
178 Paul B 28 1
199 Eve A 28 1
did name
1 cs
2 ceng
3 physics
?
13. Άρα η απάντηση στο query:
Ποιά τμήματα δεν έχουν κανένα σπουδαστή;
select *
from dept left outer join student on dept.did = student.did
where student.sid IS NULL;
Θα είναι ίδιο το αποτέλεσμα με right outer join;
13
14. Όταν τα πεδία που συνδέουν τους δύο πίνακες έχουν το ίδιο όνομα.
Παραλείπουμε τη συνθήκη σύνδεσης
Πρέπει να χρησιμοποιείται με προσοχή!!!!
select *
from dept natural join student;
Θα εμφανίσει εγγραφές? OΧΙ! “Empty set”
γιατί το πεδίο name υπάρχει και στους δύο πίνακες, αλλά με
διαφορετικό νόημα (και τιμή)
Μπορεί να χρησιμοποιηθεί και για μια εξωτερική σύνδεση
left natural join
right natural join
14
15. Δημιουργήστε τον πίνακα school (scid, name) έτσι ώστε κάθε record του
να αντιστοιχεί σε πολλά records του πίνακα dept
create table school (scid int primary key not null,
name varchar(40));
Καταχωρήστε δύο εγγραφές στον πίνακα school (1 stef, 2 hy)
insert into school (scid, name) values (1, ‘stef');
insert into school (scid, name) values (2, ‘hy’);
Αλλάξετε τη δομή του πίνακα dept ώστε να υλοποιηθεί η σχέση που περιγράφεται
προηγουμένως
alter table dept add scid int;
Ενημερώστε όλες τις εγγραφές στον πίνακα dept ώστε να δείχνουν στην εγγραφή με scid =
1 του πίνακα school
update dept set scid = 1;
15
16. Βρείτε τα ονόματα των σπουδαστών που είναι γραμμένοι στη σχολή ‘stef’.
select student.name
from school, student, dept
where school.scid=dept.scid and dept.did=student.did and school.name=‘stef’;
ή
select student.name
from school inner join dept on school.scid=dept.scid
inner join student on dept.did=student.did
where school.name=‘stef’;
16
17. Ασκήσεις
1. Βρείτε το όνομα της σχολής στην οποία είναι γραμμένος ο ‘Steve’.
2. Πόσους σπουδαστές έχει η σχολή ‘stef’;
3. Ποιές σχολές δεν έχουν καταχωρημένο κανένα τμήμα;
4. Βρείτε τις σχολές που δεν έχουν κανένα σπουδαστή δηλαδή:
είτε δεν έχουν τμήματα + είτε έχουν τμήματα αλλά όχι σπουδαστές.
Θα απαντηθεί πλήρως όταν μιλήσουμε για το Union
17
Σύνδεση περισσοτέρων πινάκων (3)Σύνδεση περισσοτέρων πινάκων (3)