File notes/code/sql/HW_ProfExample.sql added (mode: 100644) (index 0000000..41f78db) |
|
1 |
|
/* code/sql/HW_ProfExample.sql */ |
|
2 |
|
|
|
3 |
|
DROP SCHEMA IF EXISTS HW_ProfExample; |
|
4 |
|
CREATE SCHEMA HW_ProfExample; |
|
5 |
|
USE HW_ProfExample; |
|
6 |
|
|
|
7 |
|
-- start snippet tables-1 |
|
8 |
|
/* code/sql/HW_ProfExample.sql */ |
|
9 |
|
|
|
10 |
|
CREATE TABLE PROF( |
|
11 |
|
Login VARCHAR(25) PRIMARY KEY, |
|
12 |
|
Name VARCHAR(25), |
|
13 |
|
Department CHAR(5) |
|
14 |
|
); |
|
15 |
|
|
|
16 |
|
CREATE TABLE DEPARTMENT( |
|
17 |
|
Code CHAR(5) PRIMARY KEY, |
|
18 |
|
Name VARCHAR(25), |
|
19 |
|
Head VARCHAR(25), |
|
20 |
|
FOREIGN KEY (Head) REFERENCES PROF(Login) |
|
21 |
|
ON UPDATE CASCADE |
|
22 |
|
); |
|
23 |
|
|
|
24 |
|
ALTER TABLE PROF ADD FOREIGN KEY (Department) |
|
25 |
|
REFERENCES DEPARTMENT(Code); |
|
26 |
|
-- end snippet tables-1 |
|
27 |
|
|
|
28 |
|
-- start snippet tables-2 |
|
29 |
|
CREATE TABLE STUDENT( |
|
30 |
|
Login VARCHAR(25) PRIMARY KEY, |
|
31 |
|
Name VARCHAR(25), |
|
32 |
|
Registered DATE, |
|
33 |
|
Major CHAR(5), |
|
34 |
|
FOREIGN KEY (Major) REFERENCES DEPARTMENT(Code) |
|
35 |
|
); |
|
36 |
|
|
|
37 |
|
CREATE TABLE GRADE( |
|
38 |
|
Login VARCHAR(25), |
|
39 |
|
Grade INT, |
|
40 |
|
PRIMARY KEY(Login, Grade), |
|
41 |
|
FOREIGN KEY (Login) REFERENCES STUDENT(Login) |
|
42 |
|
); |
|
43 |
|
-- end snippet tables-2 |
|
44 |
|
|
|
45 |
|
|
|
46 |
|
-- start snippet insert-1 |
|
47 |
|
INSERT INTO DEPARTMENT VALUES |
|
48 |
|
('MATH', 'Mathematics', NULL), |
|
49 |
|
('CS', 'Computer Science', NULL); |
|
50 |
|
-- end snippet insert-1 |
|
51 |
|
|
|
52 |
|
-- start snippet insert-2 |
|
53 |
|
INSERT INTO DEPARTMENT (Code, Name) VALUES |
|
54 |
|
('CYBR', 'Cyber Secturity'); |
|
55 |
|
-- end snippet insert-2 |
|
56 |
|
|
|
57 |
|
-- start snippet insert-3 |
|
58 |
|
INSERT INTO PROF (Login, Department, Name) VALUES |
|
59 |
|
('caubert', 'CS', 'Clément Aubert'); |
|
60 |
|
|
|
61 |
|
INSERT INTO PROF (Login, Name, Department) VALUES |
|
62 |
|
('aturing', 'Alan Turing', 'CS'), |
|
63 |
|
('perdos', 'Paul Erdős', 'MATH'), |
|
64 |
|
('bgates', 'Bill Gates', 'CYBR'); |
|
65 |
|
|
|
66 |
|
INSERT INTO STUDENT (Login, Name, Registered, Major) VALUES |
|
67 |
|
('jrakesh', 'Jalal Rakesh', DATE'2017-12-01', 'CS'), |
|
68 |
|
('svlatka', 'Sacnite Vlatka', '2015-03-12', 'MATH'), |
|
69 |
|
('cjoella', 'Candice Joella', '20120212', 'CYBR'), |
|
70 |
|
('aalyx', 'Ava Alyx', 20121011, 'CYBR'), |
|
71 |
|
('caubert', 'Clément Aubert', NULL, 'CYBR'); |
|
72 |
|
|
|
73 |
|
INSERT INTO GRADE VALUES |
|
74 |
|
('jrakesh', 3.8), |
|
75 |
|
('svlatka', 2.5); |
|
76 |
|
-- end snippet insert-3 |
|
77 |
|
|
|
78 |
|
-- start snippet select-update |
|
79 |
|
SELECT Login FROM STUDENT; |
|
80 |
|
|
|
81 |
|
UPDATE DEPARTMENT |
|
82 |
|
SET Head = 'aturing' |
|
83 |
|
WHERE Code = 'MATH'; |
|
84 |
|
|
|
85 |
|
UPDATE DEPARTMENT |
|
86 |
|
SET Head = 'bgates' |
|
87 |
|
WHERE Code = 'CS' OR Code = 'CYBR'; |
|
88 |
|
|
|
89 |
|
SELECT Login |
|
90 |
|
FROM STUDENT |
|
91 |
|
WHERE NOT Major = 'CYBR'; |
|
92 |
|
|
|
93 |
|
SELECT Login, Name |
|
94 |
|
FROM PROF |
|
95 |
|
WHERE Department = 'CS'; |
|
96 |
|
|
|
97 |
|
SELECT Login |
|
98 |
|
FROM STUDENT |
|
99 |
|
WHERE Major = 'CYBR' |
|
100 |
|
AND |
|
101 |
|
Registered > DATE'20121001'; |
|
102 |
|
|
|
103 |
|
SELECT Login |
|
104 |
|
FROM STUDENT |
|
105 |
|
WHERE Name LIKE 'Ava%'; |
|
106 |
|
|
|
107 |
|
SELECT Name |
|
108 |
|
FROM PROF |
|
109 |
|
WHERE Login LIKE '_aubert'; |
|
110 |
|
-- end snippet select-update |
|
111 |
|
|
|
112 |
|
-- start snippet null |
|
113 |
|
INSERT INTO DEPARTMENT Values ('Hist', 'History', NULL); |
|
114 |
|
SELECT * FROM DEPARTMENT WHERE Head IS NULL; |
|
115 |
|
SELECT * FROM DEPARTMENT WHERE Head IS NOT NULL; |
|
116 |
|
SELECT COUNT(*) FROM GRADE WHERE Grade IS NULL; |
|
117 |
|
-- end snippet null |
|
118 |
|
|
|
119 |
|
-- start snippet order-by |
|
120 |
|
SELECT Login FROM GRADE |
|
121 |
|
WHERE Grade > 2.0 |
|
122 |
|
ORDER BY Grade; |
|
123 |
|
|
|
124 |
|
SELECT Login FROM GRADE |
|
125 |
|
WHERE Grade > 2.0 |
|
126 |
|
ORDER BY Grade DESC; |
|
127 |
|
|
|
128 |
|
SELECT Login, Major FROM STUDENT |
|
129 |
|
ORDER BY Major, Name; |
|
130 |
|
-- end snippet order-by |
|
131 |
|
|
|
132 |
|
-- start snippet select-project-join-1 |
|
133 |
|
SELECT Login |
|
134 |
|
FROM PROF, DEPARTMENT |
|
135 |
|
WHERE DEPARTMENT.Name = "Mathematics" |
|
136 |
|
AND |
|
137 |
|
Department = Code; |
|
138 |
|
-- end snippet select-project-join-1 |
|
139 |
|
|
|
140 |
|
-- start snippet select-project-join-2 |
|
141 |
|
SELECT Name |
|
142 |
|
FROM STUDENT, GRADE |
|
143 |
|
WHERE Grade > 3.0 |
|
144 |
|
AND |
|
145 |
|
STUDENT.Login = GRADE.Login; |
|
146 |
|
-- end snippet select-project-join-2 |
|
147 |
|
|
|
148 |
|
-- start snippet select-project-join-3 |
|
149 |
|
SELECT PROF.Name |
|
150 |
|
FROM PROF, DEPARTMENT, STUDENT |
|
151 |
|
WHERE STUDENT.Name = "Ava Alyx" |
|
152 |
|
AND |
|
153 |
|
STUDENT.Major = DEPARTMENT.Code |
|
154 |
|
AND |
|
155 |
|
DEPARTMENT.Head = PROF.Login; |
|
156 |
|
-- end snippet select-project-join-3 |
|
157 |
|
|
|
158 |
|
-- start snippet alias-1 |
|
159 |
|
SELECT PROF.Name |
|
160 |
|
FROM PROF, DEPARTMENT, STUDENT AS B |
|
161 |
|
WHERE B.Name = "Ava Alyx" |
|
162 |
|
AND |
|
163 |
|
B.Major = DEPARTMENT.Code |
|
164 |
|
AND |
|
165 |
|
DEPARTMENT.Head = PROF.Login; |
|
166 |
|
-- end snippet alias-1 |
|
167 |
|
|
|
168 |
|
-- start snippet alias-2 |
|
169 |
|
SELECT A.Name |
|
170 |
|
FROM PROF AS A, DEPARTMENT AS B, STUDENT AS C |
|
171 |
|
WHERE C.Name = "Ava Alyx" |
|
172 |
|
AND |
|
173 |
|
C.Major = B.Code |
|
174 |
|
AND |
|
175 |
|
B.Head = A.Login; |
|
176 |
|
-- end snippet alias-2 |
|
177 |
|
|
|
178 |
|
-- start snippet alias-3 |
|
179 |
|
SELECT Others.Login |
|
180 |
|
FROM GRADE AS Mine, GRADE AS Others |
|
181 |
|
WHERE Mine.Login = "aalyx" |
|
182 |
|
AND |
|
183 |
|
Mine.Grade < Others.Grade; |
|
184 |
|
-- end snippet alias-3 |
|
185 |
|
|
|
186 |
|
-- start snippet alias-4 |
|
187 |
|
SELECT JOINT.Login |
|
188 |
|
FROM PROF AS PROJECT, PROF AS JOINT |
|
189 |
|
WHERE PROJECT.Login = "caubert" |
|
190 |
|
AND |
|
191 |
|
PROJECT.Department = JOINT.Department; |
|
192 |
|
-- end snippet alias-4 |
|
193 |
|
|
|
194 |
|
-- start snippet alias-5 |
|
195 |
|
SELECT Fellow.Name AS "Fellow of Ava" |
|
196 |
|
FROM STUDENT AS Ava, STUDENT AS Fellow |
|
197 |
|
WHERE Ava.Name = "Ava Alyx" |
|
198 |
|
AND |
|
199 |
|
Fellow.Major = Ava.Major |
|
200 |
|
AND |
|
201 |
|
NOT Fellow.Login = Ava.Login; |
|
202 |
|
-- end snippet alias-5 |
|
203 |
|
|
|
204 |
|
-- start snippet nested-1 |
|
205 |
|
SELECT Login FROM GRADE |
|
206 |
|
WHERE Grade > |
|
207 |
|
(SELECT AVG(Grade) FROM GRADE); |
|
208 |
|
-- end snippet nested-1 |
|
209 |
|
|
|
210 |
|
-- start snippet nested-2 |
|
211 |
|
SELECT Login FROM GRADE |
|
212 |
|
WHERE Grade >= |
|
213 |
|
ALL (SELECT Grade FROM GRADE WHERE Grade IS NOT NULL); |
|
214 |
|
-- end snippet nested-2 |
|
215 |
|
|
|
216 |
|
-- start snippet max |
|
217 |
|
SELECT Login FROM GRADE |
|
218 |
|
WHERE Grade >= |
|
219 |
|
(SELECT MAX(Grade) FROM GRADE); |
|
220 |
|
-- end snippet max |
|
221 |
|
|
|
222 |
|
-- start snippet whodunit |
|
223 |
|
SELECT Login |
|
224 |
|
FROM PROF |
|
225 |
|
WHERE DEPARTMENT IN ( SELECT Major |
|
226 |
|
FROM STUDENT |
|
227 |
|
WHERE Login LIKE '%a'); |
|
228 |
|
-- end snippet whodunit |
|
229 |
|
|
|
230 |
|
-- start snippet transf-1a |
|
231 |
|
SELECT Login |
|
232 |
|
FROM PROF |
|
233 |
|
WHERE DEPARTMENT = ( SELECT Major |
|
234 |
|
FROM STUDENT |
|
235 |
|
WHERE Login = "cjoella"); |
|
236 |
|
-- end snippet transf-1a |
|
237 |
|
|
|
238 |
|
-- start snippet transf-1b |
|
239 |
|
SELECT PROF.Login |
|
240 |
|
FROM PROF, STUDENT |
|
241 |
|
WHERE DEPARTMENT = Major AND STUDENT.Login = "cjoella"; |
|
242 |
|
-- end snippet transf-1b |
|
243 |
|
|
|
244 |
|
-- start snippet transf-2a |
|
245 |
|
SELECT Name |
|
246 |
|
FROM STUDENT, GRADE |
|
247 |
|
WHERE Grade > 3.0 |
|
248 |
|
AND |
|
249 |
|
STUDENT.Login = GRADE.Login; |
|
250 |
|
-- end snippet transf-2a |
|
251 |
|
|
|
252 |
|
-- start snippet transf-2b |
|
253 |
|
SELECT Name FROM STUDENT |
|
254 |
|
WHERE Login IN (SELECT Login FROM GRADE WHERE Grade > 3.0); |
|
255 |
|
-- end snippet transf-2b |
File notes/lectures_notes.md changed (mode: 100644) (index 29afcce..cccf7cf) |
... |
... |
DEPARTMENT(Code (PK), Name, Head (FK to PROF.Login)) |
1971 |
1971 |
](fig/rel_mod/professor_department) |
](fig/rel_mod/professor_department) |
1972 |
1972 |
\ |
\ |
1973 |
1973 |
|
|
1974 |
|
``` |
|
1975 |
|
CREATE TABLE PROF( |
|
1976 |
|
Login VARCHAR(25) PRIMARY KEY, |
|
1977 |
|
Name VARCHAR(25), |
|
1978 |
|
Department CHAR(5) |
|
1979 |
|
); |
|
1980 |
|
|
|
1981 |
|
CREATE TABLE DEPARTMENT( |
|
1982 |
|
Code CHAR(5) PRIMARY KEY, |
|
1983 |
|
Name VARCHAR(25), |
|
1984 |
|
Head VARCHAR(25), |
|
1985 |
|
FOREIGN KEY (Head) REFERENCES PROF(Login) |
|
1986 |
|
ON UPDATE CASCADE |
|
1987 |
|
); |
|
1988 |
1974 |
|
|
1989 |
|
ALTER TABLE PROF ADD FOREIGN KEY (Department) |
|
1990 |
|
REFERENCES DEPARTMENT(Code); |
|
1991 |
|
``` |
|
|
1975 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=tables-1} |
|
1976 |
|
``` |
1992 |
1977 |
|
|
1993 |
1978 |
Note the structure of the `ALTER TABLE` command: |
Note the structure of the `ALTER TABLE` command: |
1994 |
1979 |
|
|
|
... |
... |
Note the structure of the `ALTER TABLE` command: |
1996 |
1981 |
- … `KEY (Department) REFERENCES (Code);`⇒ error |
- … `KEY (Department) REFERENCES (Code);`⇒ error |
1997 |
1982 |
- … `KEY PROF(Department) REFERENCES DEPARTMENT(Code);` ⇒ ok |
- … `KEY PROF(Department) REFERENCES DEPARTMENT(Code);` ⇒ ok |
1998 |
1983 |
|
|
1999 |
|
``` |
|
2000 |
|
CREATE TABLE STUDENT( |
|
2001 |
|
Login VARCHAR(25) PRIMARY KEY, |
|
2002 |
|
Name VARCHAR(25), |
|
2003 |
|
Registered DATE, |
|
2004 |
|
Major CHAR(5), |
|
2005 |
|
FOREIGN KEY (Major) REFERENCES DEPARTMENT(Code) |
|
2006 |
|
); |
|
2007 |
|
|
|
2008 |
|
CREATE TABLE GRADE( |
|
2009 |
|
Login VARCHAR(25), |
|
2010 |
|
Grade INT, |
|
2011 |
|
PRIMARY KEY(Login, Grade), |
|
2012 |
|
FOREIGN KEY (Login) REFERENCES STUDENT(Login) |
|
2013 |
|
); |
|
2014 |
|
``` |
|
|
1984 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=tables-2} |
|
1985 |
|
``` |
2015 |
1986 |
|
|
2016 |
1987 |
#### Populating |
#### Populating |
2017 |
1988 |
|
|
2018 |
1989 |
We can insert multiple values at once: |
We can insert multiple values at once: |
2019 |
1990 |
|
|
2020 |
|
``` |
|
2021 |
|
INSERT INTO DEPARTMENT VALUES |
|
2022 |
|
('MATH', 'Mathematics', NULL), |
|
2023 |
|
('CS', 'Computer Science', NULL); |
|
2024 |
|
``` |
|
|
1991 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=insert-1} |
|
1992 |
|
``` |
2025 |
1993 |
|
|
2026 |
1994 |
We can specify which attributes we are giving: |
We can specify which attributes we are giving: |
2027 |
1995 |
|
|
2028 |
|
``` |
|
2029 |
|
INSERT INTO DEPARTMENT (Code, Name) VALUES |
|
2030 |
|
('CYBR', 'Cyber Secturity'); |
|
2031 |
|
``` |
|
|
1996 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=insert-2} |
|
1997 |
|
``` |
2032 |
1998 |
|
|
2033 |
1999 |
And we can even specify the order (even the trivial one): |
And we can even specify the order (even the trivial one): |
2034 |
2000 |
|
|
2035 |
|
``` |
|
2036 |
|
INSERT INTO PROF (Login, Department, Name) VALUES |
|
2037 |
|
('caubert', 'CS', 'Clément Aubert'); |
|
2038 |
|
|
|
2039 |
|
INSERT INTO PROF (Login, Name, Department) VALUES |
|
2040 |
|
('aturing', 'Alan Turing', 'CS'), |
|
2041 |
|
('perdos', 'Paul Erdős', 'MATH'), |
|
2042 |
|
('bgates', 'Bill Gates', 'CYBR'); |
|
2043 |
|
|
|
2044 |
|
INSERT INTO STUDENT (Login, Name, Registered, Major) VALUES |
|
2045 |
|
('jrakesh', 'Jalal Rakesh', DATE'2017-12-01', 'CS'), |
|
2046 |
|
('svlatka', 'Sacnite Vlatka', '2015-03-12', 'MATH'), |
|
2047 |
|
('cjoella', 'Candice Joella', '20120212', 'CYBR'), |
|
2048 |
|
('aalyx', 'Ava Alyx', 20121011, 'CYBR'), |
|
2049 |
|
('caubert', 'Clément Aubert', NULL, 'CYBR'); |
|
2050 |
|
|
|
2051 |
|
INSERT INTO GRADE VALUES |
|
2052 |
|
('jrakesh', 3.8), |
|
2053 |
|
('svlatka', 2.5); |
|
2054 |
|
``` |
|
|
2001 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=insert-3} |
|
2002 |
|
``` |
2055 |
2003 |
|
|
2056 |
2004 |
Note the date literals. |
Note the date literals. |
2057 |
2005 |
|
|
|
... |
... |
Order of clauses does not matter, not even for optimization purpose. |
2063 |
2011 |
UPDATE <table> |
UPDATE <table> |
2064 |
2012 |
SET <attribute1> = <value1>, <attribute2> = <value2>, … |
SET <attribute1> = <value1>, <attribute2> = <value2>, … |
2065 |
2013 |
WHERE <condition>; |
WHERE <condition>; |
|
2014 |
|
``` |
2066 |
2015 |
|
|
|
2016 |
|
``` |
2067 |
2017 |
SELECT <attribute list, called projection attributes> |
SELECT <attribute list, called projection attributes> |
2068 |
2018 |
FROM <table list> |
FROM <table list> |
2069 |
2019 |
WHERE <condition>; |
WHERE <condition>; |
|
2020 |
|
``` |
2070 |
2021 |
|
|
|
2022 |
|
``` |
2071 |
2023 |
DELETE FROM <table list> |
DELETE FROM <table list> |
2072 |
2024 |
WHERE <condition>; |
WHERE <condition>; |
2073 |
2025 |
``` |
``` |
|
... |
... |
Conditions can |
2093 |
2045 |
- `_` will match one character (any character), `%` will match any number of character, |
- `_` will match one character (any character), `%` will match any number of character, |
2094 |
2046 |
- advanced regular expression possible using the `REGEXP` keyword. |
- advanced regular expression possible using the `REGEXP` keyword. |
2095 |
2047 |
|
|
2096 |
|
``` |
|
2097 |
|
SELECT Login FROM STUDENT; |
|
2098 |
|
|
|
2099 |
|
UPDATE DEPARTMENT |
|
2100 |
|
SET Head = 'aturing' |
|
2101 |
|
WHERE Code = 'MATH'; |
|
2102 |
|
|
|
2103 |
|
UPDATE DEPARTMENT |
|
2104 |
|
SET Head = 'bgates' |
|
2105 |
|
WHERE Code = 'CS' OR Code = 'CYBR'; |
|
2106 |
|
|
|
2107 |
|
SELECT Login |
|
2108 |
|
FROM STUDENT |
|
2109 |
|
WHERE NOT Major = 'CYBR'; |
|
2110 |
|
|
|
2111 |
|
SELECT Login, Name |
|
2112 |
|
FROM PROF |
|
2113 |
|
WHERE Department = 'CS'; |
|
2114 |
|
|
|
2115 |
|
SELECT Login |
|
2116 |
|
FROM STUDENT |
|
2117 |
|
WHERE Major = 'CYBR' |
|
2118 |
|
AND |
|
2119 |
|
Registered > DATE'20121001'; |
|
2120 |
|
|
|
2121 |
|
SELECT Login |
|
2122 |
|
FROM STUDENT |
|
2123 |
|
WHERE Name LIKE 'Ava%'; |
|
2124 |
|
|
|
2125 |
|
SELECT Name |
|
2126 |
|
FROM PROF |
|
2127 |
|
WHERE Login LIKE '_aubert'; |
|
2128 |
|
``` |
|
|
2048 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=select-update} |
|
2049 |
|
``` |
2129 |
2050 |
|
|
2130 |
2051 |
Note that `LIKE` is by default case-insensitive, both in [MariaDB](https://mariadb.com/kb/en/like/) and in [MySQL](https://dev.mysql.com/doc/refman/8.0/en/case-sensitivity.html). |
Note that `LIKE` is by default case-insensitive, both in [MariaDB](https://mariadb.com/kb/en/like/) and in [MySQL](https://dev.mysql.com/doc/refman/8.0/en/case-sensitivity.html). |
2131 |
2052 |
The `COLLATE` operator can be used to force the search to be case-sensitive, as well as `LIKE BINARY`. |
The `COLLATE` operator can be used to force the search to be case-sensitive, as well as `LIKE BINARY`. |
|
... |
... |
U | U |
2190 |
2111 |
|
|
2191 |
2112 |
You can test if a value is `NULL` with `IS NULL`. |
You can test if a value is `NULL` with `IS NULL`. |
2192 |
2113 |
|
|
2193 |
|
``` |
|
2194 |
|
INSERT INTO DEPARTMENT Values ('Hist', 'History', NULL); |
|
2195 |
|
SELECT * FROM DEPARTMENT WHERE Head IS NULL; |
|
2196 |
|
SELECT * FROM DEPARTMENT WHERE Head IS NOT NULL; |
|
2197 |
|
SELECT COUNT(*) FROM GRADE WHERE Grade IS NULL; |
|
2198 |
|
``` |
|
|
2114 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=null} |
|
2115 |
|
``` |
2199 |
2116 |
|
|
2200 |
2117 |
Note that you can not use `IS` to compare values: this key word is reserved to test if a value is (not) `NULL`, and nothing else. |
Note that you can not use `IS` to compare values: this key word is reserved to test if a value is (not) `NULL`, and nothing else. |
2201 |
2118 |
|
|
|
... |
... |
There is also `INTERSECT` and `EXCEPT` in the specification, but MySQL does not |
2282 |
2199 |
|
|
2283 |
2200 |
You can have `ORDER BY` specifications: |
You can have `ORDER BY` specifications: |
2284 |
2201 |
|
|
2285 |
|
``` |
|
2286 |
|
SELECT Login FROM GRADE |
|
2287 |
|
WHERE Grade > 2.0 |
|
2288 |
|
ORDER BY Grade; |
|
2289 |
|
|
|
2290 |
|
SELECT Login FROM GRADE |
|
2291 |
|
WHERE Grade > 2.0 |
|
2292 |
|
ORDER BY Grade DESC; |
|
2293 |
|
|
|
2294 |
|
SELECT Login, Major FROM STUDENT |
|
2295 |
|
ORDER BY Major, Name; |
|
2296 |
|
``` |
|
|
2202 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=order-by} |
|
2203 |
|
``` |
2297 |
2204 |
|
|
2298 |
2205 |
`ORDER BY` order by ascending order by default. |
`ORDER BY` order by ascending order by default. |
2299 |
2206 |
|
|
|
... |
... |
returns the number of _different names_ (which in this case is the same as the n |
2321 |
2228 |
|
|
2322 |
2229 |
Note that `AVG` returns the average of all **non-`NULL`** values, as we can see on the following example: |
Note that `AVG` returns the average of all **non-`NULL`** values, as we can see on the following example: |
2323 |
2230 |
|
|
2324 |
|
```{.sqlmysql .numberLines include=code/sql/HW_Avg.sql} |
|
|
2231 |
|
```{.sqlmysql .numberLines include=code/sql/HW_Avg.sql snippet=show-avg} |
2325 |
2232 |
``` |
``` |
2326 |
2233 |
|
|
2327 |
|
|
|
2328 |
2234 |
### Aliases for Columns |
### Aliases for Columns |
2329 |
2235 |
|
|
2330 |
2236 |
We can use aliases for the columns. |
We can use aliases for the columns. |
|
... |
... |
For nested queries, cf. [@Textbook6, 5.1.2] or [@Textbook7, 7.1.2]. |
2368 |
2274 |
|
|
2369 |
2275 |
### Select-Project-Join |
### Select-Project-Join |
2370 |
2276 |
|
|
2371 |
|
``` |
|
2372 |
|
SELECT Login |
|
2373 |
|
FROM PROF, DEPARTMENT |
|
2374 |
|
WHERE DEPARTMENT.Name = "Mathematics" |
|
2375 |
|
AND |
|
2376 |
|
Department = Code; |
|
2377 |
|
``` |
|
|
2277 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=select-project-join-1} |
|
2278 |
|
``` |
2378 |
2279 |
|
|
2379 |
2280 |
- `Department.Name = 'Mathematics'` is the selection condition |
- `Department.Name = 'Mathematics'` is the selection condition |
2380 |
2281 |
- `Department = Code` is the join condition, because it combines two tuples. |
- `Department = Code` is the join condition, because it combines two tuples. |
2381 |
2282 |
- Why do we use the fully qualified name attribute for `Name`? |
- Why do we use the fully qualified name attribute for `Name`? |
2382 |
2283 |
- We have to list all the tables we want to consult, even if we use fully qualified names. |
- We have to list all the tables we want to consult, even if we use fully qualified names. |
2383 |
2284 |
|
|
2384 |
|
``` |
|
2385 |
|
SELECT Name |
|
2386 |
|
FROM STUDENT, GRADE |
|
2387 |
|
WHERE Grade > 3.0 |
|
2388 |
|
AND |
|
2389 |
|
STUDENT.Login = GRADE.Login; |
|
2390 |
|
``` |
|
|
2285 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=select-project-join-2} |
|
2286 |
|
``` |
2391 |
2287 |
|
|
2392 |
2288 |
- `Grade > 3.0` is the selection condition |
- `Grade > 3.0` is the selection condition |
2393 |
2289 |
- `STUDENT.Login = GRADE.Login` is the join condition |
- `STUDENT.Login = GRADE.Login` is the join condition |
2394 |
2290 |
|
|
2395 |
2291 |
We can have two join conditions! |
We can have two join conditions! |
2396 |
2292 |
|
|
2397 |
|
``` |
|
2398 |
|
SELECT PROF.Name |
|
2399 |
|
FROM PROF, DEPARTMENT, STUDENT |
|
2400 |
|
WHERE STUDENT.Name = "Ava Alyx" |
|
2401 |
|
AND |
|
2402 |
|
STUDENT.Major = DEPARTMENT.Code |
|
2403 |
|
AND |
|
2404 |
|
DEPARTMENT.Head = PROF.Login; |
|
|
2293 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=select-project-join-3} |
2405 |
2294 |
``` |
``` |
2406 |
2295 |
|
|
2407 |
2296 |
Note that for the kind of join we are studiying (called "inner joins"), the [order does not matter](https://stackoverflow.com/q/9614922). |
Note that for the kind of join we are studiying (called "inner joins"), the [order does not matter](https://stackoverflow.com/q/9614922). |
|
... |
... |
Consider the following example: |
2415 |
2304 |
|
|
2416 |
2305 |
We can use aliases on tables to shorten the previous query: |
We can use aliases on tables to shorten the previous query: |
2417 |
2306 |
|
|
2418 |
|
``` |
|
2419 |
|
SELECT PROF.Name |
|
2420 |
|
FROM PROF, DEPARTMENT, STUDENT AS B |
|
2421 |
|
WHERE B.Name = "Ava Alyx" |
|
2422 |
|
AND |
|
2423 |
|
B.Major = DEPARTMENT.Code |
|
2424 |
|
AND |
|
2425 |
|
DEPARTMENT.Head = PROF.Login; |
|
|
2307 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=alias-1} |
2426 |
2308 |
``` |
``` |
2427 |
2309 |
|
|
2428 |
2310 |
We can use multiple aliases to make it even shorter (but less readable): |
We can use multiple aliases to make it even shorter (but less readable): |
2429 |
2311 |
|
|
2430 |
|
``` |
|
2431 |
|
SELECT A.Name |
|
2432 |
|
FROM PROF AS A, DEPARTMENT AS B, STUDENT AS C |
|
2433 |
|
WHERE C.Name = "Ava Alyx" |
|
2434 |
|
AND |
|
2435 |
|
C.Major = B.Code |
|
2436 |
|
AND |
|
2437 |
|
B.Head = A.Login; |
|
|
2312 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=alias-2} |
2438 |
2313 |
``` |
``` |
2439 |
2314 |
|
|
2440 |
2315 |
For those two, aliases are convenient, but not required to write the query. |
For those two, aliases are convenient, but not required to write the query. |
2441 |
2316 |
In some cases, we cannot do without aliases. |
In some cases, we cannot do without aliases. |
2442 |
2317 |
For instance if we want to compare two rows in the same table: |
For instance if we want to compare two rows in the same table: |
2443 |
2318 |
|
|
2444 |
|
``` |
|
2445 |
|
SELECT Others.Login |
|
2446 |
|
FROM GRADE AS Mine, GRADE AS Others |
|
2447 |
|
WHERE Mine.Login = "aalyx" |
|
2448 |
|
AND |
|
2449 |
|
Mine.Grade < Others.Grade; |
|
|
2319 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=alias-3} |
2450 |
2320 |
``` |
``` |
2451 |
2321 |
|
|
2452 |
2322 |
Generally, when you want to perform a join _within the same table_, then you have to "make two copies of the tables" and name them differently using aliases. |
Generally, when you want to perform a join _within the same table_, then you have to "make two copies of the tables" and name them differently using aliases. |
|
... |
... |
Let us try to write a query that answers the question |
2457 |
2327 |
We need a way of distinguising between the professors we are projecting on (the one whole login is caubert) and the one we are joining with (the ones that have the same department). |
We need a way of distinguising between the professors we are projecting on (the one whole login is caubert) and the one we are joining with (the ones that have the same department). |
2458 |
2328 |
This can be done using something like: |
This can be done using something like: |
2459 |
2329 |
|
|
2460 |
|
``` |
|
2461 |
|
SELECT JOINT.Login |
|
2462 |
|
FROM PROF AS PROJECT, PROF AS JOINT |
|
2463 |
|
WHERE PROJECT.Login = "caubert" |
|
2464 |
|
AND |
|
2465 |
|
PROJECT.Department = JOINT.Department; |
|
|
2330 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=alias-4} |
2466 |
2331 |
``` |
``` |
2467 |
2332 |
|
|
2468 |
2333 |
Note that we are "opening up two copies of the PROF tables", and naming them differently (`PROJECT` and `JOINT`). |
Note that we are "opening up two copies of the PROF tables", and naming them differently (`PROJECT` and `JOINT`). |
|
... |
... |
Note that we are "opening up two copies of the PROF tables", and naming them dif |
2471 |
2336 |
|
|
2472 |
2337 |
Another (improved) example of a similar query is |
Another (improved) example of a similar query is |
2473 |
2338 |
|
|
2474 |
|
``` |
|
2475 |
|
SELECT Fellow.Name AS "Fellow of Ava" |
|
2476 |
|
FROM STUDENT AS Ava, STUDENT AS Fellow |
|
2477 |
|
WHERE Ava.Name = "Ava Alyx" |
|
2478 |
|
AND |
|
2479 |
|
Fellow.Major = Ava.Major |
|
2480 |
|
AND |
|
2481 |
|
NOT Fellow.Login = Ava.Login; |
|
|
2339 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=alias-5} |
2482 |
2340 |
``` |
``` |
2483 |
2341 |
|
|
2484 |
2342 |
A couple of remarks about this query: |
A couple of remarks about this query: |
|
... |
... |
A couple of remarks about this query: |
2492 |
2350 |
|
|
2493 |
2351 |
Let us look at a first example |
Let us look at a first example |
2494 |
2352 |
|
|
2495 |
|
``` |
|
2496 |
|
SELECT Login FROM GRADE |
|
2497 |
|
WHERE Grade > |
|
2498 |
|
(SELECT AVG(Grade) FROM GRADE); |
|
|
2353 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=nested-1} |
2499 |
2354 |
``` |
``` |
2500 |
2355 |
|
|
2501 |
2356 |
A nested query is made of an outer query (`SELECT Login`…) and an inner query (`SELECT AVG(Grade)`…). |
A nested query is made of an outer query (`SELECT Login`…) and an inner query (`SELECT AVG(Grade)`…). |
|
... |
... |
To learn more about those operators, refer to <https://www.w3schools.com/sql/sql |
2506 |
2361 |
|
|
2507 |
2362 |
An example could be |
An example could be |
2508 |
2363 |
|
|
2509 |
|
``` |
|
2510 |
|
SELECT Login FROM GRADE |
|
2511 |
|
WHERE Grade >= |
|
2512 |
|
ALL (SELECT Grade FROM GRADE WHERE Grade IS NOT NULL); |
|
|
2364 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=nested-2} |
2513 |
2365 |
``` |
``` |
2514 |
2366 |
|
|
2515 |
2367 |
Note that |
Note that |
|
... |
... |
Note that |
2518 |
2370 |
- The part `IS NOT NULL` is needed: otherwise, if one of the grade is `NULL`, then the comparison would yelds "unknown", and no grade would be greater than all of the others. |
- The part `IS NOT NULL` is needed: otherwise, if one of the grade is `NULL`, then the comparison would yelds "unknown", and no grade would be greater than all of the others. |
2519 |
2371 |
- This query could be simplified, using `MAX`: |
- This query could be simplified, using `MAX`: |
2520 |
2372 |
|
|
2521 |
|
``` |
|
2522 |
|
SELECT Login FROM GRADE |
|
2523 |
|
WHERE Grade >= |
|
2524 |
|
(SELECT MAX(Grade) FROM GRADE); |
|
|
2373 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=max} |
2525 |
2374 |
``` |
``` |
2526 |
2375 |
|
|
2527 |
2376 |
Answering the question |
Answering the question |
|
... |
... |
Answering the question |
2530 |
2379 |
|
|
2531 |
2380 |
--that sounds like the what would ask a police officer in a whodunit-- could be answer using |
--that sounds like the what would ask a police officer in a whodunit-- could be answer using |
2532 |
2381 |
|
|
2533 |
|
``` |
|
2534 |
|
SELECT Login |
|
2535 |
|
FROM PROF |
|
2536 |
|
WHERE DEPARTMENT IN ( SELECT Major |
|
2537 |
|
FROM STUDENT |
|
2538 |
|
WHERE Login LIKE '%a'); |
|
|
2382 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=whodunit} |
2539 |
2383 |
``` |
``` |
2540 |
2384 |
|
|
2541 |
2385 |
For this query, we could not use `=`, since more than one major could be returned. |
For this query, we could not use `=`, since more than one major could be returned. |
|
... |
... |
For this query, we could not use `=`, since more than one major could be returne |
2543 |
2387 |
Furthermore, nested query that uses `=` can often be rewritten without being nested. |
Furthermore, nested query that uses `=` can often be rewritten without being nested. |
2544 |
2388 |
For instance, |
For instance, |
2545 |
2389 |
|
|
2546 |
|
``` |
|
2547 |
|
SELECT Login |
|
2548 |
|
FROM PROF |
|
2549 |
|
WHERE DEPARTMENT = ( SELECT Major |
|
2550 |
|
FROM STUDENT |
|
2551 |
|
WHERE Login = "cjoella"); |
|
|
2390 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=transf-1a} |
2552 |
2391 |
``` |
``` |
2553 |
2392 |
|
|
2554 |
2393 |
becomes |
becomes |
2555 |
2394 |
|
|
2556 |
|
``` |
|
2557 |
|
SELECT PROF.Login |
|
2558 |
|
FROM PROF, STUDENT |
|
2559 |
|
WHERE DEPARTMENT = Major AND STUDENT.Login = "cjoella"; |
|
|
2395 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=transf-1b} |
2560 |
2396 |
``` |
``` |
2561 |
2397 |
|
|
2562 |
2398 |
Conversly, you can sometimes write select-project-join as nested queries |
Conversly, you can sometimes write select-project-join as nested queries |
2563 |
2399 |
For instance, |
For instance, |
2564 |
2400 |
|
|
2565 |
|
``` |
|
2566 |
|
SELECT Name |
|
2567 |
|
FROM STUDENT, GRADE |
|
2568 |
|
WHERE Grade > 3.0 |
|
2569 |
|
AND |
|
2570 |
|
STUDENT.Login = GRADE.Login; |
|
|
2401 |
|
|
|
2402 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=transf-2a} |
2571 |
2403 |
``` |
``` |
2572 |
2404 |
|
|
2573 |
2405 |
becomes |
becomes |
2574 |
2406 |
|
|
|
2407 |
|
|
|
2408 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProfExample.sql snippet=transf-2b} |
2575 |
2409 |
``` |
``` |
2576 |
|
SELECT Name FROM STUDENT |
|
2577 |
|
WHERE Login IN (SELECT Login FROM GRADE WHERE Grade > 3.0); |
|
|
2410 |
|
|
|
2411 |
|
## Procedures |
|
2412 |
|
|
|
2413 |
|
A "stored" procedure is a `SQL` function statements that can take arguments and may be called from another part of your program. |
|
2414 |
|
Stated differently, a procedure is a serie of statements stored in a schema, that can easily be executed repeatedly, cf. <https://dev.mysql.com/doc/refman/8.0/en/create-procedure.html> or <https://mariadb.com/kb/en/library/create-procedure/>. |
|
2415 |
|
|
|
2416 |
|
Imagine we have the following: |
|
2417 |
|
|
|
2418 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProcedureExamples.sql snippet=procedure-1} |
2578 |
2419 |
``` |
``` |
2579 |
2420 |
|
|
|
2421 |
|
`SQL` is extremely litteral: when it reads the delimiter `;`, it _must_ execute the command that was shared. |
|
2422 |
|
But a procedure, being composed of commands, will contain the `;` symbol. |
|
2423 |
|
To "solve" this (weird) issue, and be able to define a procedure, we have to "temporarily alter the language", using `DELIMITER //` that makes the delimiter being `//` instead of `;`[^note-on-delimiter]. |
2580 |
2424 |
|
|
2581 |
|
## Procedures |
|
|
2425 |
|
[^note-on-delimiter]: |
|
2426 |
|
The symbols `$$` are often used too, and the documentation, at <https://dev.mysql.com/doc/refman/8.0/en/stored-programs-defining.html>, reads: |
2582 |
2427 |
|
|
2583 |
|
A "stored" procedure is a series of `SQL` statements that can be "called" from another part of your program. |
|
2584 |
|
It is pretty much like defining a function, and, exactly like a function, it can takes arguments. |
|
2585 |
|
In MariaDB, you could have the following program. |
|
|
2428 |
|
> You can redefine the delimiter to a string other than `//` and the delimiter can consist of a single character or multiple characters. You should avoid the use of the backslash (`\`) character because that is the escape character for MySQL. |
2586 |
2429 |
|
|
|
2430 |
|
The minus sign twice is also a poor choice, since it is used for commenting. |
2587 |
2431 |
|
|
2588 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProcedureExamples.sql} |
|
|
2432 |
|
In any case, we can then define and execute a simpe procedure called `STUDENTLIST` as follows: |
|
2433 |
|
|
|
2434 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProcedureExamples.sql snippet=procedure-2} |
|
2435 |
|
``` |
|
2436 |
|
|
|
2437 |
|
A procedure an also take arguments, and an example could be: |
|
2438 |
|
|
|
2439 |
|
|
|
2440 |
|
```{.sqlmysql .numberLines include=code/sql/HW_ProcedureExamples.sql snippet=procedure-3} |
2589 |
2441 |
``` |
``` |
2590 |
2442 |
|
|
2591 |
2443 |
## Triggers |
## Triggers |
|
... |
... |
A trigger is a series of statements stored in a schema that can be automatically |
2594 |
2446 |
Triggers are extremely powerfull, and are a way of automating part of the work in your database. |
Triggers are extremely powerfull, and are a way of automating part of the work in your database. |
2595 |
2447 |
In MariaDB, you could have the following program. |
In MariaDB, you could have the following program. |
2596 |
2448 |
|
|
|
2449 |
|
Imagine we have the following: |
|
2450 |
|
|
|
2451 |
|
```{.sqlmysql .numberLines include=code/sql/HW_TriggerExample.sql snippet=trigger-1} |
|
2452 |
|
``` |
|
2453 |
|
|
|
2454 |
|
We want to create a trigger that counts the number of times something was inserted in our `STUDENT` table. |
|
2455 |
|
`SQL` supports some primitive form of variables (cf. <https://dev.mysql.com/doc/refman/8.0/en/user-variables.html> and <https://mariadb.com/kb/en/library/user-defined-variables/>). |
|
2456 |
|
There is no "clear" form of type, <https://dev.mysql.com/doc/refman/8.0/en/user-variables.html> reads: |
|
2457 |
|
|
|
2458 |
|
> In addition, the default result type of a variable is based on its type at the beginning of the statement. This may have unintended effects if a variable holds a value of one type at the beginning of a |
|
2459 |
|
statement in which it is also assigned a new value of a different type. To avoid problems with this behavior, either do not assign a value to and read the value of the same variable within a single statement, or else set the variable to 0, 0.0, or '' to define its type before you use it. |
|
2460 |
|
|
|
2461 |
|
In other words, `SQL` just "guess" the type of your value and go with it. |
|
2462 |
|
Creating a simple trigger that increment a variable every time an insertion is performed in the `STUDENT` table can be done as follows: |
|
2463 |
|
|
|
2464 |
|
```{.sqlmysql .numberLines include=code/sql/HW_TriggerExample.sql snippet=trigger-2} |
|
2465 |
|
``` |
|
2466 |
|
|
|
2467 |
|
Now, assume we want to create a trigger that calculates the average for us. |
|
2468 |
|
Note that the trigger will need to manipulate two tables (`STUDENT` and `GRADE`) at the same time. |
2597 |
2469 |
|
|
2598 |
|
```{.sqlmysql .numberLines include=code/sql/HW_TriggerExample.sql} |
|
|
2470 |
|
```{.sqlmysql .numberLines include=code/sql/HW_TriggerExample.sql snippet=trigger-3} |
2599 |
2471 |
``` |
``` |
2600 |
2472 |
|
|
|
2473 |
|
The source code contains examples of insertion and explanations on how to witness the trigger in action. |
2601 |
2474 |
|
|
2602 |
2475 |
## Setting Up Your Work Environment {#sec:setup} |
## Setting Up Your Work Environment {#sec:setup} |
2603 |
2476 |
|
|
|
... |
... |
The following links could be useful: |
2645 |
2518 |
#. Save the "mysql-installer-web-community-XXX.msi" file, and open it. If there is an updated version of the installer available, agree to download it. Accept the license term. |
#. Save the "mysql-installer-web-community-XXX.msi" file, and open it. If there is an updated version of the installer available, agree to download it. Accept the license term. |
2646 |
2519 |
#. We will now install the various components needed for this class, leaving all the choices by defaults. This means that you need to do the following: |
#. We will now install the various components needed for this class, leaving all the choices by defaults. This means that you need to do the following: |
2647 |
2520 |
#. Leave the first option on "Developer Default" and click on "Next", or click on "Custom", and select the following: |
#. Leave the first option on "Developer Default" and click on "Next", or click on "Custom", and select the following: |
2648 |
|
|
|
2649 |
|
{width=90%} |
|
2650 |
|
|
|
|
2521 |
|
{width=90%}\ |
2651 |
2522 |
#. Click on "Next" even if you do not meet all the requirements |
#. Click on "Next" even if you do not meet all the requirements |
2652 |
2523 |
#. Click on "Execute". The system will download and install several softwares (this may take some time). |
#. Click on "Execute". The system will download and install several softwares (this may take some time). |
2653 |
2524 |
#. Click on "Next" twice, leave "Type and Networking" on "Standalone MySQL Server / Classic MySQL Replication" and click "Next", and leave the next options as they are (unless you know what you do and want to change the port, for instance) and click on "Next". |
#. Click on "Next" twice, leave "Type and Networking" on "Standalone MySQL Server / Classic MySQL Replication" and click "Next", and leave the next options as they are (unless you know what you do and want to change the port, for instance) and click on "Next". |
|
... |
... |
Exercise +.# |
2977 |
2848 |
|
|
2978 |
2849 |
Data type | Examples | |
Data type | Examples | |
2979 |
2850 |
--- | --- | |
--- | --- | |
2980 |
|
| `4`, `-32` |
|
|
2851 |
|
| `4`, `-32` |
2981 |
2852 |
Char(4) | |
Char(4) | |
2982 |
2853 |
VarChar(10) | `'Train'`, `'Michelle'` |
VarChar(10) | `'Train'`, `'Michelle'` |
2983 |
2854 |
Bit(4) | |
Bit(4) | |
2984 |
|
| `TRUE`, `UNKNOWN` |
|
|
2855 |
|
| `TRUE`, `UNKNOWN` |
2985 |
2856 |
|
|
2986 |
2857 |
Exercise +.#sqldatatype |
Exercise +.#sqldatatype |
2987 |
2858 |
|
|
|
... |
... |
Solution +.# |
3234 |
3105 |
|
|
3235 |
3106 |
Data type | Examples |
Data type | Examples |
3236 |
3107 |
--- | --- |
--- | --- |
3237 |
|
Int | `4`, `-32` |
|
3238 |
|
Char(4) | `'trai'`, `'plol'` |
|
3239 |
|
VarChar(10) | `'Train'`, `'Michelle'` |
|
3240 |
|
Bit(4) | `B'1010'`, `B'0101'` |
|
3241 |
|
Boolean | `TRUE`, `UNKNOWN` |
|
|
3108 |
|
`INT` | `4`, `-32` |
|
3109 |
|
`CHAR(4)` | `'abCD'`, `"dEfG"` |
|
3110 |
|
`VARCHAR(10)` | `'Train'`, `'Michelle'` |
|
3111 |
|
`BIT(4)` | `B'1010'`, `B'0101'` |
|
3112 |
|
`BOOL`` | `TRUE`, `FALSE`, `NULL` |
|
3113 |
|
|
|
3114 |
|
`NULL` is actually a valid answer for every single type of |
3242 |
3115 |
|
|
3243 |
3116 |
Solution +.# |
Solution +.# |
3244 |
3117 |
|
|
|
... |
... |
Solution +.# |
3252 |
3125 |
~ |
~ |
3253 |
3126 |
A simple and compact code could be: |
A simple and compact code could be: |
3254 |
3127 |
|
|
3255 |
|
``` |
|
3256 |
|
-- You can ignore the first three lines. |
|
3257 |
|
DROP SCHEMA IF EXISTS HW_SHORT; |
|
3258 |
|
CREATE SCHEMA HW_SHORT; |
|
3259 |
|
USE HW_SHORT; |
|
3260 |
|
CREATE TABLE A(Att1 INT PRIMARY KEY, Att2 INT); |
|
3261 |
|
CREATE TABLE B(Att3 INT PRIMARY KEY, Att4 INT, FOREIGN KEY (Att4) REFERENCES A(Att1)); |
|
3262 |
|
INSERT INTO A VALUES (1, 2); |
|
3263 |
|
INSERT INTO B VALUES (3, 1); |
|
|
3128 |
|
```{.sqlmysql .numberLines include=code/sql/HW_Short.sql snippet=solution} |
3264 |
3129 |
``` |
``` |
3265 |
3130 |
|
|
3266 |
3131 |
Solution +.# |
Solution +.# |
|
... |
... |
Problem (Constraints on foreign keys) +.#fk |
3652 |
3517 |
Problem (Revisiting the PROF table) +.#profrevisited |
Problem (Revisiting the PROF table) +.#profrevisited |
3653 |
3518 |
~ |
~ |
3654 |
3519 |
|
|
3655 |
|
Create the `PROF`, `STUDENT`, `DEPARTMENT` and `GRADE` tables as in the ["Constructing and populating a new example"](#sec:profexample) section. |
|
|
3520 |
|
Create the `PROF`, `DEPARTMENT`, `STUDENT` and `GRADE` tables as in the ["Constructing and populating a new example"](#sec:profexample) section. |
3656 |
3521 |
Populate them with some data (copy it from the notes or come up with your own data). |
Populate them with some data (copy it from the notes or come up with your own data). |
3657 |
3522 |
|
|
3658 |
3523 |
@problem:profrevisited -- Question -.# |
@problem:profrevisited -- Question -.# |
|
... |
... |
Problem (Read, correct, and write `SQL` statements for the COFFEE database) +.#c |
3826 |
3691 |
#. Every statement respects `SQL`'s syntax (there's no "a semi-colon is missing" trap). |
#. Every statement respects `SQL`'s syntax (there's no "a semi-colon is missing" trap). |
3827 |
3692 |
#. None of these commands are actually executed; the data is always in the state depicted above. |
#. None of these commands are actually executed; the data is always in the state depicted above. |
3828 |
3693 |
|
|
3829 |
|
You can use **COFFEE**.1 to denote the first tuple (or row) in **COFFEE**, and similarly for other relations and tuples (so that, for instance, **SUPPLY**.$4$ corresponds to `"Johns & Co"., 221`). |
|
|
3694 |
|
You can use **COFFEE**.1 to denote the first tuple (or row) in **COFFEE**, and similarly for other relations and tuples (so that, for instance, **SUPPLY**.$4$ corresponds to `"Johns & Co"., 221`). |
3830 |
3695 |
|
|
3831 |
3696 |
@problem:coffee -- Question -.# |
@problem:coffee -- Question -.# |
3832 |
3697 |
|
|
|
... |
... |
Solution to [%D %n (%T)](#problem:fk) |
4554 |
4419 |
|
|
4555 |
4420 |
Solution to [%D %n (%T)](#problem:profrevisited) |
Solution to [%D %n (%T)](#problem:profrevisited) |
4556 |
4421 |
~ |
~ |
|
4422 |
|
|
4557 |
4423 |
|
|
4558 |
|
For Questions 1 and 5, we should have: |
|
|
4424 |
|
@problem:profrevisited-- Solution to Q. -.# |
|
4425 |
|
~ |
|
4426 |
|
|
|
4427 |
|
Ignoring the LECTURE relation, we have: |
4559 |
4428 |
|
|
4560 |
4429 |
 |
4565 |
4434 |
](fig/rel_mod/professor_department_extended) |
](fig/rel_mod/professor_department_extended) |
4566 |
4435 |
\ |
\ |
4567 |
4436 |
|
|
|
4437 |
|
@problem:profrevisited-- Solution to Q. -.# |
|
4438 |
|
~ |
|
4439 |
|
|
|
4440 |
|
|
4568 |
4441 |
For the other questions, refer to this code. |
For the other questions, refer to this code. |
4569 |
4442 |
|
|
4570 |
4443 |
```{.sqlmysql .numberLines include=code/sql/HW_Lecture.sql} |
```{.sqlmysql .numberLines include=code/sql/HW_Lecture.sql} |