Skip to content

Commit 3a68acb

Browse files
committed
filtering, join and aggregrations
1 parent 0bba187 commit 3a68acb

File tree

1 file changed

+262
-0
lines changed

1 file changed

+262
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,262 @@
1+
/********** Filterig, Join and Aggregration ************/
2+
3+
/* we want to know person's salary comparing to his/her department average salary */
4+
SELECT
5+
s.last_name,s.salary,s.department,
6+
(SELECT ROUND(AVG(salary),2)
7+
FROM staff s2
8+
WHERE s2.department = s.department) AS department_average_salary
9+
FROM staff s;
10+
11+
12+
/* how many people are earning above/below the average salary of his/her department ? */
13+
CREATE VIEW vw_salary_comparision_by_department
14+
AS
15+
SELECT
16+
s.department,
17+
(
18+
s.salary > (SELECT ROUND(AVG(s2.salary),2)
19+
FROM staff s2
20+
WHERE s2.department = s.department)
21+
)AS is_higher_than_dept_avg_salary
22+
FROM staff s
23+
ORDER BY s.department;
24+
25+
26+
SELECT * FROM vw_salary_comparision_by_department;
27+
28+
SELECT department, is_higher_than_dept_avg_salary, COUNT(*) AS total_employees
29+
FROM vw_salary_comparision_by_department
30+
GROUP BY 1,2;
31+
32+
33+
----------------------------------------------------------------------------------------------
34+
35+
/* Assume that people who earn at latest 100,000 salary is Executive.
36+
We want to know the average salary for executives for each department.
37+
38+
Data Interpretation: it seem like Sports department has the highest average salary for Executives
39+
where Movie department has the lowest.*/
40+
SELECT department, ROUND(AVG(salary),2) AS average_salary
41+
FROM staff
42+
WHERE salary >= 100000
43+
GROUP BY department
44+
ORDER BY 2 DESC;
45+
46+
47+
/* who earn the most in the company?
48+
It seems like Stanley Grocery earns the most.
49+
*/
50+
SELECT last_name, department, salary
51+
FROM staff
52+
WHERE salary = (
53+
SELECT MAX(s2.salary)
54+
FROM staff s2
55+
);
56+
57+
58+
59+
/* who earn the most in his/her own department */
60+
SELECT s.department, s.last_name, s.salary
61+
FROM staff s
62+
WHERE s.salary = (
63+
SELECT MAX(s2.salary)
64+
FROM staff s2
65+
WHERE s2.department = s.department
66+
)
67+
ORDER BY 1;
68+
69+
----------------------------------------------------------------------------------------------
70+
71+
SELECT * FROM company_divisions;
72+
73+
/* full details info of employees with company division
74+
Based on the results, we see that there are only 953 rows returns. We know that there are 1000 staffs.
75+
*/
76+
SELECT s.last_name, s.department, cd.company_division
77+
FROM staff s
78+
JOIN company_divisions cd
79+
ON cd.department = s.department;
80+
81+
82+
/* now all 1000 staffs are returned, but some 47 people have missing company - division.*/
83+
SELECT s.last_name, s.department, cd.company_division
84+
FROM staff s
85+
LEFT JOIN company_divisions cd
86+
ON cd.department = s.department;
87+
88+
89+
/* who are those people with missing company division?
90+
Data Interpretation: it seems like all staffs from "books" department have missing company division.
91+
We may want to inform our IT team to add Books department in corresponding company division.
92+
*/
93+
SELECT s.last_name, s.department, cd.company_division
94+
FROM staff s
95+
LEFT JOIN company_divisions cd
96+
ON cd.department = s.department
97+
WHERE company_division IS NULL;
98+
99+
100+
----------------------------------------------------------------------------------------------
101+
102+
CREATE VIEW vw_staff_div_reg AS
103+
SELECT s.*, cd.company_division, cr.company_regions
104+
FROM staff s
105+
LEFT JOIN company_divisions cd ON s.department = cd.department
106+
LEFT JOIN company_regions cr ON s.region_id = cr.region_id;
107+
108+
109+
SELECT COUNT(*)
110+
FROM vw_staff_div_reg;
111+
112+
113+
/* How many staffs are in each company regions */
114+
SELECT company_regions, COUNT(*) AS total_employees
115+
FROM vw_staff_div_reg
116+
GROUP BY 1
117+
ORDER BY 1;
118+
119+
120+
SELECT company_regions, company_division, COUNT(*) AS total_employees
121+
FROM vw_staff_div_reg
122+
GROUP BY 1,2
123+
ORDER BY 1,2;
124+
125+
126+
/***** Grouping Sets *****************/
127+
-- Grouping Sets : allows to have more than one grouping in the results table
128+
-- there is no need to seperately use group by per query statement
129+
130+
-- 2 groupings
131+
SELECT company_regions, company_division, COUNT(*) AS total_employees
132+
FROM vw_staff_div_reg
133+
GROUP BY
134+
GROUPING SETS(company_regions, company_division)
135+
ORDER BY 1,2;
136+
137+
138+
-- 3 groupings
139+
SELECT company_regions, company_division, gender, COUNT(*) AS total_employees
140+
FROM vw_staff_div_reg
141+
GROUP BY
142+
GROUPING SETS(company_regions, company_division, gender)
143+
ORDER BY 1, 2
144+
145+
----------------------------------------------------------------------------------------------
146+
147+
148+
CREATE OR REPLACE VIEW vw_staff_div_reg_country AS
149+
SELECT s.*, cd.company_division, cr.company_regions, cr.country
150+
FROM staff s
151+
LEFT JOIN company_divisions cd ON s.department = cd.department
152+
LEFT JOIN company_regions cr ON s.region_id = cr.region_id;
153+
154+
/* employees per regions and country */
155+
SELECT company_regions, country, COUNT(*) AS total_employees
156+
FROM vw_staff_div_reg_country
157+
GROUP BY
158+
company_regions, country
159+
ORDER BY country, company_regions;
160+
161+
-------------- ROLL UP & CUBE to create Sub Totals ----------------------------------------
162+
-- both are sub clauses of Group by
163+
164+
165+
-------------- ROLL UP ----------------
166+
-- is used to generate sub totals and grand totals
167+
168+
/* number of employees per regions & country, Then sub totals per Country, Then toal for whole table*/
169+
SELECT country,company_regions, COUNT(*) AS total_employees
170+
FROM vw_staff_div_reg_country
171+
GROUP BY
172+
ROLLUP(country, company_regions)
173+
ORDER BY country, company_regions;
174+
175+
176+
----------- CUBE -------------------
177+
SELECT company_division, company_regions, COUNT(*) AS total_employees
178+
FROM vw_staff_div_reg_country
179+
GROUP BY
180+
CUBE(company_division, company_regions)
181+
ORDER BY company_division, company_regions;
182+
183+
184+
-------------------------------------------------------------------------------
185+
186+
/* Difference between Roll Up and Cube
187+
188+
Reference: https://www.postgresqltutorial.com/postgresql-rollup/
189+
190+
For example, the CUBE (c1,c2,c3) makes all eight possible grouping sets:
191+
(c1, c2, c3)
192+
(c1, c2)
193+
(c2, c3)
194+
(c1,c3)
195+
(c1)
196+
(c2)
197+
(c3)
198+
()
199+
200+
201+
However, the ROLLUP(c1,c2,c3) generates only four grouping sets, assuming the hierarchy c1 > c2 > c3 as follows:
202+
203+
(c1, c2, c3)
204+
(c1, c2)
205+
(c1)
206+
()
207+
208+
*/
209+
210+
SELECT company_division, company_regions, country, COUNT(*) AS total_employees
211+
FROM vw_staff_div_reg_country
212+
GROUP BY
213+
ROLLUP(company_division, company_regions, country)
214+
ORDER BY company_division, company_regions, country;
215+
216+
217+
SELECT company_division, company_regions, country, COUNT(*) AS total_employees
218+
FROM vw_staff_div_reg_country
219+
GROUP BY
220+
CUBE(company_division, company_regions, country)
221+
ORDER BY company_division, company_regions, country;
222+
223+
224+
-------------------------------------------------------------------------------
225+
226+
------------ FETCH FIRST ----------
227+
/*
228+
Fetch First works different from Limit.
229+
230+
For Fetch First, Order By Clause works first for sorting. Then Fetch First selets the rows.
231+
232+
For Limit, Limit acutally limits the rows and then performs the operations.
233+
234+
*/
235+
236+
237+
/* What are the top salary earners ? */
238+
SELECT last_name, salary
239+
FROM staff
240+
ORDER BY salary DESC
241+
FETCH FIRST 10 ROWS ONLY;
242+
243+
244+
/* Top 5 division with highest number of employees*/
245+
SELECT
246+
company_division,
247+
COUNT(*) AS total_employees
248+
FROM vw_staff_div_reg_country
249+
GROUP BY company_division
250+
ORDER BY company_division
251+
FETCH FIRST 5 ROWS ONLY;
252+
253+
254+
255+
SELECT
256+
company_division,
257+
COUNT(*) AS total_employees
258+
FROM vw_staff_div_reg_country
259+
GROUP BY company_division
260+
ORDER BY company_division
261+
LIMIT 5;
262+

0 commit comments

Comments
 (0)