-
Notifications
You must be signed in to change notification settings - Fork 1
/
mysql_joins_notes.sql
283 lines (229 loc) · 6.76 KB
/
mysql_joins_notes.sql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
/*
Joins are an essential part of SQL, they put the relational in the relational database.
Joins are necessary to extract information that is divided into several tables because of sanity of data
and derive insights from it.
These are the joins : 1. INNER JOIN (or JOIN)
2. LEFT OUTER JOIN (or LEFT JOIN)
3. RIGHT OUTER JOIN (or RIGHT JOIN)
4. SELF JOIN
5. CROSS JOIN
6. UNION
*/
# Let's create sample table duplicates to run the experiments on
CREATE TABLE IF NOT EXISTS departments_dup(
dept_no CHAR(4),
dept_name VARCHAR(40)
);
INSERT INTO departments_dup (dept_no, dept_name)
(SELECT dept_no, dept_name FROM departments);
SELECT * FROM departments_dup;
INSERT INTO departments_dup (dept_name) VALUES ('Public Relations');
DELETE FROM departments_dup WHERE dept_no = 'd002';
DROP TABLE IF EXISTS dept_manager_dup;
CREATE TABLE dept_manager_dup (
emp_no int(11) NOT NULL,
dept_no char(4) NULL,
from_date date NOT NULL,
to_date date NULL
);
INSERT INTO dept_manager_dup
select * from dept_manager;
INSERT INTO dept_manager_dup (emp_no, from_date)
VALUES (999904, '2017-01-01'),
(999905, '2017-01-01'),
(999906, '2017-01-01'),
(999907, '2017-01-01');
DELETE FROM dept_manager_dup
WHERE
dept_no = 'd001';
####### 1. INNER JOIN #######
/*
INNER JOIN joins the tables at the intersection, that is only keeps those records from both tables, which have matching entries on the join
column.
INNER JOIN can be defined using two ways, either using INNER JOIN or just JOIN.
*/
# Let's join the departments_dup and dept_manager_dup on dept_no
SELECT
DM.dept_no, DM.emp_no, D.dept_name
FROM
dept_manager_dup DM
JOIN
departments_dup D ON DM.dept_no = D.dept_no
ORDER BY DM.dept_no;
# Order doesn't matter in INNER JOIN.
# So the above is equivalent to
SELECT
DM.dept_no, DM.emp_no, D.dept_name
FROM
departments_dup D
INNER JOIN
dept_manager_dup DM ON D.dept_no = DM.dept_no
ORDER BY DM.dept_no;
# Excercise on INNER JOIN
/*
Extract list containing information about all managers
emp_no, first_name, last_name, dept_no, hire_date
*/
# We'll need the dept_manager and the employees table to extract this information
# as the dept_manager table contains info about managers and their dept_nos
SELECT
E.emp_no, E.first_name, E.last_name, D.dept_no, E.hire_date
FROM
employees E
INNER JOIN
dept_manager D ON E.emp_no = D.emp_no
ORDER BY E.emp_no;
####### 2. LEFT JOIN #######
/*
LEFT JOIN returns all the values of the table at the left of the operator and the ones matching with the right on the ON column
order of the table names matter in this.
It can also be written as LEFT OUTER JOIN as it is a type of outer join.
*/
# Left join exercise
SELECT
E.emp_no, E.first_name, E.last_name, D.dept_no, D.from_date
FROM
employees E
LEFT JOIN
dept_manager D ON E.emp_no = D.emp_no
WHERE
E.last_name = 'Markovitch'
ORDER BY D.dept_no DESC , E.emp_no;
# We can see that only one employee has a from_date column, that means only one employee is
# in dept_manager table that is also in employees table, so there is only one employee who is a
# manager with a last name Markovitch
####### 3. RIGHT JOIN #######
/*
RIGHT JOIN is basically a LEFT JOIN with inverted order of table names and is seldom used.
it can be also written as RIGHT JOIN or RIGHT OUTER JOIN
All entries from the table on the right will be included and entries from the table on the left
will only be included if they have a matching entry on the ON column with the right table.
*/
####### 4. CROSS JOIN #######
/*
CROSS JOIN is basically a cartesian product, that is, each entry from one table matched with each entry of other table
there's no ON parameter here.
It is same as using INNER JOIN without an ON parameter or SELECTing from multiple tables
*/
# Example
SELECT
DM.*, D.*
FROM
dept_manager_dup DM
CROSS JOIN
departments_dup D
ORDER BY D.dept_no , DM.emp_no;
# Is similar to
SELECT
DM.*, D.*
FROM
dept_manager_dup DM
INNER JOIN
departments_dup D
ORDER BY D.dept_no , DM.emp_no;
#Is similar to
SELECT
DM.*, D.*
FROM
dept_manager_dup DM,
departments_dup D
ORDER BY D.dept_no , DM.emp_no;
# Excercise
/*
Use a CROSS JOIN to return a list with all possible combinations between managers from the dept_manager table and department number 9.
*/
SELECT
DM.*, D.*
FROM
dept_manager_dup DM
CROSS JOIN
departments_dup D
WHERE
D.dept_no = 'd009'
ORDER BY DM.dept_no , DM.emp_no DESC;
/*
Return a list with the first 10 employees with all the departments they can be assigned to.
Hint: Don’t use LIMIT; use a WHERE clause.
*/
SELECT
e.*, d.*
FROM
employees e
CROSS JOIN
departments d
WHERE
e.emp_no < 10011
ORDER BY e.emp_no , d.dept_name;
/*
Select all managers’ first and last name, hire date, job title, start date, and department name.
*/
SELECT
E.emp_no,
E.first_name,
E.last_name,
E.hire_date,
T.title,
DM.from_date,
D.dept_name
FROM
dept_manager DM
JOIN
departments D ON DM.dept_no = D.dept_no
JOIN
employees E ON E.emp_no = DM.emp_no
JOIN
titles T ON DM.emp_no = T.emp_no
WHERE T.title = 'Manager'
ORDER BY E.emp_no
;
/*
Select department name and average salaries for all managers in those departments
*/
SELECT
D.dept_name, AVG(S.salary) AS avg_salary
FROM
dept_manager DM
JOIN
departments D ON DM.dept_no = D.dept_no
JOIN
salaries S ON DM.emp_no = S.emp_no
GROUP BY dept_name
HAVING avg_salary > 60000
ORDER BY avg_salary DESC
;
/*
How many males and how many female managers are there in employees database?
*/
SELECT
E.gender, COUNT(DM.emp_no) AS num_employees
FROM
dept_manager DM
JOIN
employees E ON E.emp_no = DM.emp_no
GROUP BY E.gender
ORDER BY num_employees DESC;
####### 6. UNION and UNION ALL #######
/*
UNION and UNION ALL are used to combine two tables with each having the same columns, of relative data types
It's basically appending one table entries at the end of the other table.
If one of the tables is missing any columns from the other table, NULL AS column_name is used to proxy null values
in that column.
UNION is same as UNION ALL just that UNION ALL returns duplicates from the table and UNION doesn't
*/
# Let's combine departments and department manager tables
SELECT
NULL AS emp_no,
D.dept_no,
D.dept_name,
NULL AS from_date,
NULL AS to_date
FROM
departments D
UNION ALL SELECT
DM.emp_no,
DM.dept_no,
NULL AS dept_name,
DM.from_date,
DM.to_date
FROM
dept_manager DM;