forked from MrLRTripp/HackerRank-LeetCode-StrataScratch-SQL
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathHackerRank Occupations.sql
More file actions
117 lines (91 loc) · 3.33 KB
/
HackerRank Occupations.sql
File metadata and controls
117 lines (91 loc) · 3.33 KB
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
set search_path to data_sci
-- Pivot the Occupation column in OCCUPATIONS so that each Name is sorted alphabetically
-- and displayed underneath its corresponding Occupation. The output column headers
-- should be Doctor, Professor, Singer, and Actor, respectively.
-- Note: Print NULL when there are no more names corresponding to an occupation.
-- We'll use employees table since it has same info
with name_agg as(
select distinct job_title,
array_agg(last_name) over (partition by job_title order by job_title)
from employees
order by job_title
select distinct job_title, last_name,
row_number() over (partition by job_title order by job_title) as row_num
from employees
order by job_title, row_num
select distinct job_title, count(job_title)
from employees
group by job_title
order by job_title, row_num
-- This is an interesting problem.
-- Just pick three job titles from employees
-- partition by job_title and assign a row number by last_name
-- The first last_name for each job_title will get row_num=1
-- The second last_name for each job_title will get row_num=2, etc.
-- The case statement puts the last_names in the aliased columns
-- The outer select does a group by row_num so all the values with same
-- row_num are on the same row.
-- group by requires an aggregation function. We need one that works on text so
-- use min or max. There is only one value for each row_num so either will work.
with cte as(
select
case when job_title='financial advisor' then last_name end as Advisor,
case when job_title='financial analyst' then last_name end as Analyst,
case when job_title='food chemist' then last_name end as Chemist,
row_number() over (partition by job_title order by last_name) as row_num
from employees
order by row_num)
select max(Advisor) as Advisor, -- max works the same as min
min(Analyst) as Analyst,
min(Chemist) as Chemist
from cte
GROUP by row_num
order by row_num
-- SQLServer and Oracle have pivot clauses
-- Postgres soes have a tablefunc module that provides a crosstab function
-- that can perform pivots
-- Just for fun, create a stored procedure that inserts results into table
drop PROCEDURE if EXISTS AAC
drop TABLE if exists AAC;
create table AAC (
aac_id integer generated by default as identity,
advisors text,
analysts text,
chemists text
);
CREATE PROCEDURE aac()
LANGUAGE sql
as $$
set search_path to data_sci;
insert into AAC
(advisors, analysts, chemists)
(with cte as(
select
case when job_title='financial advisor' then last_name end as Advisor,
case when job_title='financial analyst' then last_name end as Analyst,
case when job_title='food chemist' then last_name end as Chemist,
row_number() over (partition by job_title order by last_name) as row_num
from employees
order by row_num)
select max(Advisor) as Advisor, -- max works the same as min
min(Analyst) as Analyst,
min(Chemist) as Chemist
from cte
GROUP by row_num
order by row_num);
delete from AAC
where advisors is NULL and
analysts is NULL and
chemists is NULL
$$
call AAC()
-- Get salary stats
select round(avg(salary), 2), round(stddev(salary),2),
round(mode() within group (order by salary),2),
round(percentile_cont(0.5) within group (order by salary)::numeric, 2) as median
from employees
-- Histogram with $5000 bins
select floor(salary/5000)*5000, count(*)
from employees
group by 1
order by 1