├── Intermediate SQL
├── Readme_Dataset
├── 4. Window Functions.pdf
├── 1. We'll Take The Case.pdf
├── 2. Short and Simple Subqueries.pdf
├── 3. Correlated Queries, Nested Queries, and Common Table Expressions.pdf
├── 2. Short and Simple Subqueries.sql
├── 4. Window Functions.sql
├── 3. Correlated Queries, Nested Queries, and Common Table Expressions.sql
└── 1. We'll Take The Case.sql
├── Joining Data in SQL
├── 4) Subqueries.pdf
├── DATASET
│ ├── diagrams.zip
│ ├── leaders2.zip
│ └── countries2.zip
├── 3) Set theory clauses.pdf
├── 1) Introduction to joins.pdf
├── 2) Outer joins and cross joins.pdf
├── 3) Set theory clauses.sql
└── 4) Subqueries.sql
├── PostgreSQL Summary Stats and Window Functions
├── 4.Beyond Window Functions.pdf
├── 2.Fetching, ranking, and paging.pdf
├── 1.Introduction To Window Functions.pdf
├── 3.Aggregate window functions and frames.pdf
├── 2.Fetching, ranking, and paging.sql
├── 1.Introduction To Window Functions.sql
├── 3.Aggregate window functions and frames.sql
└── 4.Beyond Window Functions.sql
├── Functions for Manipulating Data in PostgreSQL
├── 1.Overview of Common Data Types.pdf
├── 3.Parsing and Manipulating Text.pdf
├── 4.Full-text Search and PostgresSQL Extensions.pdf
├── 2.Working with DATE-TIME Functions and Operators.pdf
├── 1.Overview of Common Data Types.sql
├── 3.Parsing and Manipulating Text.sql
├── 4.Full-text Search and PostgresSQL Extensions.sql
├── DATASET
│ └── postgres-sakila-incremental-schema_06172019.sql
└── 2.Working with DATE-TIME Functions and Operators.sql
└── README.md
/Intermediate SQL/Readme_Dataset:
--------------------------------------------------------------------------------
1 | There is no data set is provided for this 'Intermediate SQL' Course by Datacamp.org
2 |
--------------------------------------------------------------------------------
/Joining Data in SQL/4) Subqueries.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Novartus/Datacamp_SQL/HEAD/Joining Data in SQL/4) Subqueries.pdf
--------------------------------------------------------------------------------
/Intermediate SQL/4. Window Functions.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Novartus/Datacamp_SQL/HEAD/Intermediate SQL/4. Window Functions.pdf
--------------------------------------------------------------------------------
/Joining Data in SQL/DATASET/diagrams.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Novartus/Datacamp_SQL/HEAD/Joining Data in SQL/DATASET/diagrams.zip
--------------------------------------------------------------------------------
/Joining Data in SQL/DATASET/leaders2.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Novartus/Datacamp_SQL/HEAD/Joining Data in SQL/DATASET/leaders2.zip
--------------------------------------------------------------------------------
/Intermediate SQL/1. We'll Take The Case.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Novartus/Datacamp_SQL/HEAD/Intermediate SQL/1. We'll Take The Case.pdf
--------------------------------------------------------------------------------
/Joining Data in SQL/DATASET/countries2.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Novartus/Datacamp_SQL/HEAD/Joining Data in SQL/DATASET/countries2.zip
--------------------------------------------------------------------------------
/Joining Data in SQL/3) Set theory clauses.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Novartus/Datacamp_SQL/HEAD/Joining Data in SQL/3) Set theory clauses.pdf
--------------------------------------------------------------------------------
/Joining Data in SQL/1) Introduction to joins.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Novartus/Datacamp_SQL/HEAD/Joining Data in SQL/1) Introduction to joins.pdf
--------------------------------------------------------------------------------
/Intermediate SQL/2. Short and Simple Subqueries.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Novartus/Datacamp_SQL/HEAD/Intermediate SQL/2. Short and Simple Subqueries.pdf
--------------------------------------------------------------------------------
/Joining Data in SQL/2) Outer joins and cross joins.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Novartus/Datacamp_SQL/HEAD/Joining Data in SQL/2) Outer joins and cross joins.pdf
--------------------------------------------------------------------------------
/PostgreSQL Summary Stats and Window Functions /4.Beyond Window Functions.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Novartus/Datacamp_SQL/HEAD/PostgreSQL Summary Stats and Window Functions /4.Beyond Window Functions.pdf
--------------------------------------------------------------------------------
/Functions for Manipulating Data in PostgreSQL/1.Overview of Common Data Types.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Novartus/Datacamp_SQL/HEAD/Functions for Manipulating Data in PostgreSQL/1.Overview of Common Data Types.pdf
--------------------------------------------------------------------------------
/Functions for Manipulating Data in PostgreSQL/3.Parsing and Manipulating Text.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Novartus/Datacamp_SQL/HEAD/Functions for Manipulating Data in PostgreSQL/3.Parsing and Manipulating Text.pdf
--------------------------------------------------------------------------------
/PostgreSQL Summary Stats and Window Functions /2.Fetching, ranking, and paging.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Novartus/Datacamp_SQL/HEAD/PostgreSQL Summary Stats and Window Functions /2.Fetching, ranking, and paging.pdf
--------------------------------------------------------------------------------
/PostgreSQL Summary Stats and Window Functions /1.Introduction To Window Functions.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Novartus/Datacamp_SQL/HEAD/PostgreSQL Summary Stats and Window Functions /1.Introduction To Window Functions.pdf
--------------------------------------------------------------------------------
/Intermediate SQL/3. Correlated Queries, Nested Queries, and Common Table Expressions.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Novartus/Datacamp_SQL/HEAD/Intermediate SQL/3. Correlated Queries, Nested Queries, and Common Table Expressions.pdf
--------------------------------------------------------------------------------
/PostgreSQL Summary Stats and Window Functions /3.Aggregate window functions and frames.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Novartus/Datacamp_SQL/HEAD/PostgreSQL Summary Stats and Window Functions /3.Aggregate window functions and frames.pdf
--------------------------------------------------------------------------------
/Functions for Manipulating Data in PostgreSQL/4.Full-text Search and PostgresSQL Extensions.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Novartus/Datacamp_SQL/HEAD/Functions for Manipulating Data in PostgreSQL/4.Full-text Search and PostgresSQL Extensions.pdf
--------------------------------------------------------------------------------
/Functions for Manipulating Data in PostgreSQL/2.Working with DATE-TIME Functions and Operators.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Novartus/Datacamp_SQL/HEAD/Functions for Manipulating Data in PostgreSQL/2.Working with DATE-TIME Functions and Operators.pdf
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # SQL Fundamentals
2 |
3 |
4 |
5 |
6 |
7 |
8 | It contains the SQL solution of the following tracks with DataSet.
9 | - Joining Data In SQL
10 | - Intermediate SQL
11 | - PostgreSQL Summary Stats and Window Functions
12 | - Functions for Manipulating Data in PostgreSQL
--------------------------------------------------------------------------------
/Functions for Manipulating Data in PostgreSQL/1.Overview of Common Data Types.sql:
--------------------------------------------------------------------------------
1 | /*
2 | -- Text data types
3 | Q: Which of the following is not a valid text data type in PostgreSQL?
4 | A: STRING
5 | */
6 |
7 | /*
8 | In relational databases, the information schema is an ANSI-standard set of read-only views which provide information about all of the tables, views, columns, and procedures in a database.
9 | */
10 |
11 | -- Getting information about your database
12 | -- (1)
13 | SELECT *
14 | FROM INFORMATION_SCHEMA.TABLES
15 | WHERE table_schema = 'public';
16 |
17 | -- (2)
18 | SELECT *
19 | FROM INFORMATION_SCHEMA.COLUMNS
20 | WHERE table_name = 'actor';
21 |
22 | -- Determining data types
23 | SELECT
24 | column_name,
25 | data_type
26 | FROM INFORMATION_SCHEMA.COLUMNS
27 | -- For the customer table
28 | WHERE table_name = 'customer';
29 |
30 | /*
31 | -- Properties of date and time data types
32 | Q: Which of the following is NOT correct?
33 | A: TIME data types are stored with a timezone by default.
34 | */
35 |
36 | -- Interval data types
37 | SELECT
38 | rental_date,
39 | return_date,
40 | rental_date + INTERVAL '3 days' AS expected_return_date
41 | FROM rental;
42 |
43 | -- Accessing data in an ARRAY
44 | -- (1)
45 | SELECT
46 | title,
47 | special_features
48 | FROM film;
49 |
50 | -- (2)
51 | SELECT
52 | title,
53 | special_features
54 | FROM film
55 |
56 | -- (3)
57 | SELECT
58 | title,
59 | special_features
60 | FROM film
61 | WHERE special_features[2] = 'Deleted Scenes';
62 |
63 | -- Searching an ARRAY with ANY
64 | SELECT
65 | title,
66 | special_features
67 | FROM film
68 | WHERE 'Trailers' = ANY (special_features);
69 |
70 | -- Searching an ARRAY with @>
71 | SELECT
72 | title,
73 | special_features
74 | FROM film
75 | WHERE special_features @> ARRAY['Deleted Scenes'];
--------------------------------------------------------------------------------
/Joining Data in SQL/3) Set theory clauses.sql:
--------------------------------------------------------------------------------
1 | -- Union
2 |
3 | SELECT *
4 | FROM economies2010
5 | UNION
6 | SELECT *
7 | FROM economies2015
8 | ORDER BY CODE, YEAR;
9 |
10 |
11 | -- Union (2)
12 | SELECT country_code
13 | FROM cities
14 | UNION
15 | SELECT code
16 | FROM currencies
17 | Order BY country_code;
18 |
19 | -- Union all
20 |
21 | SELECT code, year
22 | FROM economies
23 | UNION ALL
24 | SELECT country_code, year
25 | FROM populations
26 | ORDER BY code, year;
27 |
28 | -- Intersect
29 |
30 | SELECT code, year
31 | FROM economies
32 | INTERSECT
33 | SELECT country_code, year
34 | FROM populations
35 | ORDER BY code, year;
36 |
37 | -- Intersect (2)
38 |
39 | SELECT name
40 | FROM countries
41 | INTERSECT
42 | SELECT name
43 | FROM cities;
44 |
45 | -- Review union and intersect
46 | -- Q:- Which of the following combinations of terms and definitions is correct?
47 | -- Ans:- INTERSECT: returns only records appearing in both tables
48 |
49 | -- Except
50 |
51 | SELECT name
52 | FROM cities
53 | EXCEPT
54 | SELECT capital
55 | FROM countries
56 | ORDER BY name;
57 |
58 | -- Except (2)
59 |
60 | SELECT capital
61 | FROM countries
62 | EXCEPT
63 | SELECT name
64 | FROM cities
65 | ORDER BY capital;
66 |
67 | -- Semi-join
68 | 1)
69 | SELECT country.code
70 | FROM countries AS country
71 | WHERE country.region = 'Middle East';
72 |
73 | 2)
74 | SELECT DISTINCT lang.name
75 | FROM languages AS lang
76 | ORDER BY lang.name;
77 |
78 | -- Relating semi-join to a tweaked inner join
79 | Ans: DISTNICT
80 |
81 | -- Diagnosing problems using anti-join
82 | 1)
83 | SELECT COUNT(*)
84 | FROM countries
85 | WHERE continent = 'Oceania';
86 |
87 | 2)
88 | SELECT c1.code, c1.name, c2.basic_unit AS currency
89 | FROM countries AS c1
90 | INNER JOIN currencies AS c2
91 | USING (code)
92 | WHERE continent = 'Oceania';
93 |
94 | 3)
95 | SELECT c1.code, c1.name
96 | FROM countries AS c1
97 | WHERE c1.continent = 'Oceania'
98 | AND code NOT IN
99 | (SELECT code
100 | FROM currencies);
101 |
102 | -- Set theory challenge
103 | SELECT name
104 | FROM cities AS c1
105 | WHERE country_code IN
106 | (
107 | SELECT e.code
108 | FROM economies AS e
109 | UNION
110 | SELECT c2.code
111 | FROM currencies AS c2
112 | EXCEPT
113 | SELECT p.country_code
114 | FROM populations AS p
115 | );
116 |
117 |
118 |
119 |
--------------------------------------------------------------------------------
/Functions for Manipulating Data in PostgreSQL/3.Parsing and Manipulating Text.sql:
--------------------------------------------------------------------------------
1 | -- Concatenating strings
2 | -- (1)
3 | SELECT first_name || ' ' || last_name || ' <' || email || '>' AS full_email FROM customer
4 |
5 | -- (2)
6 | SELECT CONCAT(first_name, ' ', last_name, ' <', email, '>') AS full_email FROM customer
7 |
8 | -- Changing the case of string data
9 | SELECT
10 | UPPER(c.name)
11 | || ': ' || INITCAP(f.title) AS film_category,
12 | LOWER(f.description) AS description
13 | FROM
14 | film AS f
15 | INNER JOIN film_category AS fc
16 | ON f.film_id = fc.film_id
17 | INNER JOIN category AS c
18 | ON fc.category_id = c.category_id;
19 |
20 | -- Replacing string data
21 | SELECT
22 | REPLACE(title, ' ', '_') AS title
23 | FROM film;
24 |
25 | -- Determining the length of strings
26 | SELECT
27 | title,
28 | description,
29 | CHAR_LENGTH(description) AS desc_len
30 | FROM film;
31 |
32 | -- Truncating strings
33 | SELECT
34 | LEFT(description, 50) AS short_desc
35 | FROM
36 | film AS f;
37 |
38 | -- Extracting substrings from text data
39 | SELECT
40 | SUBSTRING(address FROM POSITION(' ' IN address)+1 FOR LENGTH(address))
41 | FROM
42 | address;
43 |
44 | -- Combining functions for string manipulation
45 | SELECT
46 | SUBSTRING(email FOR POSITION('@' IN email)-1) AS username,
47 | SUBSTRING(email FROM POSITION('@' IN email)+1 FOR CHAR_LENGTH(email)) AS domain
48 | FROM customer;
49 |
50 | -- Padding
51 | -- (1)
52 | SELECT
53 | RPAD(first_name, LENGTH(first_name)+1) || last_name AS full_name
54 | FROM customer;
55 |
56 | -- (2)
57 | SELECT
58 | first_name || LPAD(last_name, LENGTH(last_name)+1) AS full_name
59 | FROM customer;
60 |
61 | -- (3)
62 | SELECT
63 | RPAD(first_name, LENGTH(first_name)+1)
64 | || RPAD(last_name, LENGTH(last_name)+2, ' <')
65 | || RPAD(email, LENGTH(email)+1, '>') AS full_email
66 | FROM customer;
67 |
68 | -- The TRIM function
69 | SELECT
70 | CONCAT(UPPER(c.name), ': ', f.title) AS film_category,
71 | TRIM(LEFT(description, 50)) AS film_desc
72 | FROM
73 | film AS f
74 | INNER JOIN film_category AS fc
75 | ON f.film_id = fc.film_id
76 | INNER JOIN category AS c
77 | ON fc.category_id = c.category_id;
78 |
79 | -- Putting it all together
80 | SELECT
81 | UPPER(c.name) || ': ' || f.title AS film_category,
82 | LEFT(description, 50 -
83 | POSITION(
84 | ' ' IN REVERSE(LEFT(description, 50))
85 | )
86 | )
87 | FROM
88 | film AS f
89 | INNER JOIN film_category AS fc
90 | ON f.film_id = fc.film_id
91 | INNER JOIN category AS c
92 | ON fc.category_id = c.category_id;
--------------------------------------------------------------------------------
/Functions for Manipulating Data in PostgreSQL/4.Full-text Search and PostgresSQL Extensions.sql:
--------------------------------------------------------------------------------
1 | -- A review of the LIKE operator
2 | -- (1)
3 | SELECT *
4 | FROM film
5 | WHERE title LIKE 'GOLD%';
6 |
7 | -- (2)
8 | SELECT *
9 | FROM film
10 | WHERE title LIKE '%GOLD';
11 |
12 | -- (3)
13 | SELECT *
14 | FROM film
15 | WHERE title LIKE '%GOLD%';
16 |
17 | -- What is a tsvector?
18 | SELECT to_tsvector(description)
19 | FROM film;
20 |
21 | -- Basic full-text search
22 | SELECT title, description
23 | FROM film
24 | WHERE to_tsvector(title) @@ to_tsquery('elf');
25 |
26 | -- User-defined data types
27 | -- (1)
28 | CREATE TYPE compass_position AS ENUM (
29 | 'North',
30 | 'West',
31 | 'South',
32 | 'East'
33 | );
34 |
35 | -- (2)
36 | CREATE TYPE compass_position AS ENUM (
37 | 'North',
38 | 'South',
39 | 'East',
40 | 'West'
41 | );
42 | SELECT typname
43 | FROM pg_type
44 | WHERE typname='compass_position';
45 |
46 | -- Getting info about user-defined data types
47 | -- (1)
48 | SELECT column_name, data_type, udt_name
49 | FROM INFORMATION_SCHEMA.COLUMNS
50 | WHERE table_name ='film' and column_name='rating';
51 |
52 | -- (2)
53 | SELECT *
54 | FROM pg_type
55 | WHERE typname='mpaa_rating'
56 |
57 | -- User-defined functions in Sakila
58 | -- (1)
59 | SELECT
60 | f.title,
61 | r.rental_id,
62 | i.inventory_id
63 | FROM film as f
64 | INNER JOIN inventory AS i ON f.film_id=i.film_id
65 | INNER JOIN rental AS r on i.inventory_id=r.inventory_id
66 |
67 | -- (2)
68 | SELECT
69 | f.title,
70 | r.rental_id,
71 | i.inventory_id,
72 | inventory_held_by_customer(i.inventory_id) AS held_by_cust
73 | FROM film as f
74 | INNER JOIN inventory AS i ON f.film_id=i.film_id
75 | INNER JOIN rental AS r on i.inventory_id=r.inventory_id
76 |
77 | -- (3)
78 | SELECT
79 | f.title,
80 | r.rental_id,
81 | i.inventory_id,
82 | inventory_held_by_customer(i.inventory_id) as held_by_cust
83 | FROM film as f
84 | INNER JOIN inventory AS i ON f.film_id=i.film_id
85 | INNER JOIN rental AS r on i.inventory_id=r.inventory_id
86 | WHERE
87 | inventory_held_by_customer(i.inventory_id) IS NOT NULL
88 |
89 | -- Enabling extensions
90 | -- (1)
91 | CREATE EXTENSION IF NOT EXISTS pg_trgm;
92 |
93 | -- (2)
94 | SELECT *
95 | FROM pg_extension;
96 |
97 | -- Measuring similarity between two strings
98 | SELECT
99 | title,
100 | description,
101 | similarity(title, description)
102 | FROM film
103 |
104 | -- Levenshtein distance examples
105 | SELECT
106 | title,
107 | description,
108 | levenshtein(title, 'JET NEIGHBOR') AS distance
109 | FROM
110 | film
111 | ORDER BY 3
112 |
113 | -- Putting it all together
114 | -- (1)
115 | SELECT
116 | title,
117 | description
118 | FROM
119 | film
120 | WHERE
121 | to_tsvector(description) @@
122 | to_tsquery('Astounding & Drama');
123 |
124 | -- (2)
125 | SELECT
126 | title,
127 | description,
128 | similarity(description, 'Astounding Drama')
129 | FROM
130 | film
131 | WHERE
132 | to_tsvector(description) @@
133 | to_tsquery('Astounding & Drama')
134 | ORDER BY
135 | similarity(description, 'Astounding Drama') DESC;
--------------------------------------------------------------------------------
/PostgreSQL Summary Stats and Window Functions /2.Fetching, ranking, and paging.sql:
--------------------------------------------------------------------------------
1 | -- Future gold medalists
2 | WITH Discus_Medalists AS (
3 | SELECT DISTINCT
4 | Year,
5 | Athlete
6 | FROM Summer_Medals
7 | WHERE Medal = 'Gold'
8 | AND Event = 'Discus Throw'
9 | AND Gender = 'Women'
10 | AND Year >= 2000)
11 |
12 | SELECT
13 | Year,
14 | Athlete,
15 | LEAD(Athlete,3) OVER (ORDER BY Year ASC) AS Future_Champion
16 | FROM Discus_Medalists
17 | ORDER BY Year ASC;
18 |
19 | -- First athlete by name
20 | WITH All_Male_Medalists AS (
21 | SELECT DISTINCT
22 | Athlete
23 | FROM Summer_Medals
24 | WHERE Medal = 'Gold'
25 | AND Gender = 'Men')
26 |
27 | SELECT
28 | athlete,
29 | FIRST_VALUE(athlete) OVER (
30 | ORDER BY athlete ASC
31 | ) AS First_Athlete
32 | FROM All_Male_Medalists;
33 |
34 | -- Last country by name
35 | WITH Hosts AS (
36 | SELECT DISTINCT Year, City
37 | FROM Summer_Medals)
38 |
39 | SELECT
40 | Year,
41 | City,
42 | LAST_VALUE(City) OVER (
43 | ORDER BY Year ASC
44 | RANGE BETWEEN
45 | UNBOUNDED PRECEDING AND
46 | UNBOUNDED FOLLOWING
47 | ) AS Last_City
48 | FROM Hosts
49 | ORDER BY Year ASC;
50 |
51 | -- Ranking athletes by medals earned
52 | WITH Athlete_Medals AS (
53 | SELECT
54 | Athlete,
55 | COUNT(*) AS Medals
56 | FROM Summer_Medals
57 | GROUP BY Athlete)
58 |
59 | SELECT
60 | Athlete,
61 | Medals,
62 | RANK() OVER (ORDER BY Medals DESC) AS Rank_N
63 | FROM Athlete_Medals
64 | ORDER BY Medals DESC;
65 |
66 | -- Ranking athletes from multiple countries
67 | WITH Athlete_Medals AS (
68 | SELECT
69 | Country, Athlete, COUNT(*) AS Medals
70 | FROM Summer_Medals
71 | WHERE
72 | Country IN ('JPN', 'KOR')
73 | AND Year >= 2000
74 | GROUP BY Country, Athlete
75 | HAVING COUNT(*) > 1)
76 |
77 | SELECT
78 | Country,
79 | Athlete,
80 | DENSE_RANK() OVER (PARTITION BY Country
81 | ORDER BY Medals DESC) AS Rank_N
82 | FROM Athlete_Medals
83 | ORDER BY Country ASC, RANK_N ASC;
84 |
85 | /*
86 | Q: DENSE_RANK's output
87 |
88 | You have the following table:
89 |
90 | | Country | Medals |
91 | |---------|--------|
92 | | IRN | 23 |
93 | | IRQ | 19 |
94 | | LBN | 19 |
95 | | SYR | 19 |
96 | | BHR | 7 |
97 | | KSA | 3 |
98 |
99 | If you were to use DENSE_RANK to order the Medals column in descending order, what rank would BHR be assigned?
100 |
101 | ANS: 3
102 | */
103 |
104 | -- Paging events
105 | WITH Events AS (
106 | SELECT DISTINCT Event
107 | FROM Summer_Medals)
108 |
109 | SELECT
110 | Event,
111 | NTILE(111) OVER (ORDER BY Event ASC) AS Page
112 | FROM Events
113 | ORDER BY Event ASC;
114 |
115 | -- Top, middle, and bottom thirds
116 | -- (1)
117 | WITH Athlete_Medals AS (
118 | SELECT Athlete, COUNT(*) AS Medals
119 | FROM Summer_Medals
120 | GROUP BY Athlete
121 | HAVING COUNT(*) > 1)
122 |
123 | SELECT
124 | Athlete,
125 | Medals,
126 | NTILE(3) OVER (ORDER BY Medals DESC) AS Third
127 | FROM Athlete_Medals
128 | ORDER BY Medals DESC, Athlete ASC;
129 |
130 | -- (2)
131 | WITH Athlete_Medals AS (
132 | SELECT Athlete, COUNT(*) AS Medals
133 | FROM Summer_Medals
134 | GROUP BY Athlete
135 | HAVING COUNT(*) > 1),
136 |
137 | Thirds AS (
138 | SELECT
139 | Athlete,
140 | Medals,
141 | NTILE(3) OVER (ORDER BY Medals DESC) AS Third
142 | FROM Athlete_Medals)
143 |
144 | SELECT
145 | Third,
146 | AVG(Medals) AS Avg_Medals
147 | FROM Thirds
148 | GROUP BY Third
149 | ORDER BY Third ASC;
--------------------------------------------------------------------------------
/Functions for Manipulating Data in PostgreSQL/DATASET/postgres-sakila-incremental-schema_06172019.sql:
--------------------------------------------------------------------------------
1 | CREATE TYPE mpaa_rating AS ENUM (
2 | 'G',
3 | 'PG',
4 | 'PG-13',
5 | 'R',
6 | 'NC-17'
7 | );
8 |
9 |
10 | ALTER TABLE film
11 | ALTER COLUMN rating TYPE mpaa_rating USING rating::mpaa_rating,
12 | ALTER COLUMN rating SET DEFAULT 'G'::mpaa_rating;
13 |
14 | CREATE OR REPLACE FUNCTION get_customer_balance(p_customer_id integer, p_effective_date timestamp with time zone) RETURNS numeric
15 | LANGUAGE plpgsql
16 | AS $$
17 | --#OK, WE NEED TO CALCULATE THE CURRENT BALANCE GIVEN A CUSTOMER_ID AND A DATE
18 | --#THAT WE WANT THE BALANCE TO BE EFFECTIVE FOR. THE BALANCE IS:
19 | --# 1) RENTAL FEES FOR ALL PREVIOUS RENTALS
20 | --# 2) ONE DOLLAR FOR EVERY DAY THE PREVIOUS RENTALS ARE OVERDUE
21 | --# 3) IF A FILM IS MORE THAN RENTAL_DURATION * 2 OVERDUE, CHARGE THE REPLACEMENT_COST
22 | --# 4) SUBTRACT ALL PAYMENTS MADE BEFORE THE DATE SPECIFIED
23 | DECLARE
24 | v_rentfees DECIMAL(5,2); --#FEES PAID TO RENT THE VIDEOS INITIALLY
25 | v_overfees INTEGER; --#LATE FEES FOR PRIOR RENTALS
26 | v_payments DECIMAL(5,2); --#SUM OF PAYMENTS MADE PREVIOUSLY
27 | BEGIN
28 | SELECT COALESCE(SUM(film.rental_rate),0) INTO v_rentfees
29 | FROM film, inventory, rental
30 | WHERE film.film_id = inventory.film_id
31 | AND inventory.inventory_id = rental.inventory_id
32 | AND rental.rental_date <= p_effective_date
33 | AND rental.customer_id = p_customer_id;
34 |
35 | SELECT COALESCE(SUM(IF((rental.return_date - rental.rental_date) > (film.rental_duration * '1 day'::interval),
36 | ((rental.return_date - rental.rental_date) - (film.rental_duration * '1 day'::interval)),0)),0) INTO v_overfees
37 | FROM rental, inventory, film
38 | WHERE film.film_id = inventory.film_id
39 | AND inventory.inventory_id = rental.inventory_id
40 | AND rental.rental_date <= p_effective_date
41 | AND rental.customer_id = p_customer_id;
42 |
43 | SELECT COALESCE(SUM(payment.amount),0) INTO v_payments
44 | FROM payment
45 | WHERE payment.payment_date <= p_effective_date
46 | AND payment.customer_id = p_customer_id;
47 |
48 | RETURN v_rentfees + v_overfees - v_payments;
49 | END
50 | $$;
51 |
52 | CREATE OR REPLACE FUNCTION inventory_held_by_customer(p_inventory_id integer) RETURNS integer
53 | LANGUAGE plpgsql
54 | AS $$
55 | DECLARE
56 | v_customer_id INTEGER;
57 | BEGIN
58 |
59 | SELECT customer_id INTO v_customer_id
60 | FROM rental
61 | WHERE return_date IS NULL
62 | AND inventory_id = p_inventory_id;
63 |
64 | RETURN v_customer_id;
65 | END $$;
66 |
67 | CREATE OR REPLACE FUNCTION inventory_in_stock(p_inventory_id integer) RETURNS boolean
68 | LANGUAGE plpgsql
69 | AS $$
70 | DECLARE
71 | v_rentals INTEGER;
72 | v_out INTEGER;
73 | BEGIN
74 | -- AN ITEM IS IN-STOCK IF THERE ARE EITHER NO ROWS IN THE rental TABLE
75 | -- FOR THE ITEM OR ALL ROWS HAVE return_date POPULATED
76 |
77 | SELECT count(*) INTO v_rentals
78 | FROM rental
79 | WHERE inventory_id = p_inventory_id;
80 |
81 | IF v_rentals = 0 THEN
82 | RETURN TRUE;
83 | END IF;
84 |
85 | SELECT COUNT(rental_id) INTO v_out
86 | FROM inventory LEFT JOIN rental USING(inventory_id)
87 | WHERE inventory.inventory_id = p_inventory_id
88 | AND rental.return_date IS NULL;
89 |
90 | IF v_out > 0 THEN
91 | RETURN FALSE;
92 | ELSE
93 | RETURN TRUE;
94 | END IF;
95 | END $$;
96 |
--------------------------------------------------------------------------------
/PostgreSQL Summary Stats and Window Functions /1.Introduction To Window Functions.sql:
--------------------------------------------------------------------------------
1 | -- Which of the following is FALSE?
2 | -- Ans:Window functions can open a "window" to another table, whereas GROUP BY functions cannot.
3 |
4 | -- Numbering rows
5 | SELECT
6 | *,
7 | ROW_NUMBER() OVER() AS Row_N
8 | FROM Summer_Medals
9 | ORDER BY Row_N ASC;
10 |
11 | -- Numbering Olympic games in ascending order
12 | SELECT
13 | Year,
14 | ROW_NUMBER() OVER() AS Row_N
15 | FROM (
16 | SELECT DISTINCT year
17 | FROM Summer_Medals
18 | ORDER BY Year ASC
19 | ) AS Years
20 | ORDER BY Year ASC;
21 |
22 | -- Numbering Olympic games in descending order
23 | SELECT
24 | Year,
25 | ROW_NUMBER() OVER (ORDER BY Year DESC) AS Row_N
26 | FROM (
27 | SELECT DISTINCT Year
28 | FROM Summer_Medals
29 | ) AS Years
30 | ORDER BY Year;
31 |
32 | -- Numbering Olympic athletes by medals earned
33 | -- (1)
34 | SELECT
35 | athlete,
36 | COUNT(sport) AS Medals
37 | FROM Summer_Medals
38 | GROUP BY Athlete
39 | ORDER BY Medals DESC;
40 |
41 | -- (2)
42 | WITH Athlete_Medals AS (
43 | SELECT
44 | Athlete,
45 | COUNT(*) AS Medals
46 | FROM Summer_Medals
47 | GROUP BY Athlete)
48 |
49 | SELECT
50 | Athlete,
51 | ROW_NUMBER() OVER (ORDER BY Medals DESC) AS Row_N
52 | FROM Athlete_Medals
53 | ORDER BY Medals DESC;
54 |
55 | -- Reigning weightlifting champions
56 | -- (1)
57 | SELECT
58 | Year,
59 | Country AS champion
60 | FROM Summer_Medals
61 | WHERE
62 | Discipline = 'Weightlifting' AND
63 | Event = '69KG' AND
64 | Gender = 'Men' AND
65 | Medal = 'Gold';
66 |
67 | -- (2)
68 | WITH Weightlifting_Gold AS (
69 | SELECT
70 | Year,
71 | Country AS champion
72 | FROM Summer_Medals
73 | WHERE
74 | Discipline = 'Weightlifting' AND
75 | Event = '69KG' AND
76 | Gender = 'Men' AND
77 | Medal = 'Gold')
78 |
79 | SELECT
80 | Year, Champion,
81 | LAG(Champion) OVER
82 | (ORDER BY Weightlifting_Gold ASC) AS Last_Champion
83 | FROM Weightlifting_Gold
84 | ORDER BY Year ASC;
85 |
86 | -- Reigning champions by gender
87 | WITH Tennis_Gold AS (
88 | SELECT DISTINCT
89 | Gender, Year, Country
90 | FROM Summer_Medals
91 | WHERE
92 | Year >= 2000 AND
93 | Event = 'Javelin Throw' AND
94 | Medal = 'Gold')
95 |
96 | SELECT
97 | Gender, Year,
98 | Country AS Champion,
99 | LAG(Country) OVER (PARTITION BY Gender
100 | ORDER BY Year ASC) AS Last_Champion
101 | FROM Tennis_Gold
102 | ORDER BY Gender ASC, Year ASC;
103 |
104 | -- Reigning champions by gender and event
105 | WITH Athletics_Gold AS (
106 | SELECT DISTINCT
107 | Gender, Year, Event, Country
108 | FROM Summer_Medals
109 | WHERE
110 | Year >= 2000 AND
111 | Discipline = 'Athletics' AND
112 | Event IN ('100M', '10000M') AND
113 | Medal = 'Gold')
114 |
115 | SELECT
116 | Gender, Year, Event,
117 | Country AS Champion,
118 | LAG(Country) OVER (PARTITION BY Gender, Event
119 | ORDER BY Year ASC) AS Last_Champion
120 | FROM Athletics_Gold
121 | ORDER BY Event ASC, Gender ASC, Year ASC;
122 |
123 |
124 | /*
125 | -- Row numbers with partitioning
126 |
127 | If you run ROW_NUMBER() OVER (PARTITION BY Year ORDER BY Medals DESC) on the following table, what row number would the 2008 Iranian record have?
128 |
129 | | Year | Country | Medals |
130 | |------|---------|--------|
131 | | 2004 | IRN | 32 |
132 | | 2004 | LBN | 17 |
133 | | 2004 | KSA | 4 |
134 | | 2008 | IRQ | 29 |
135 | | 2008 | IRN | 27 |
136 | | 2008 | UAE | 12 |
137 |
138 | -- Ans: 2
139 | */
--------------------------------------------------------------------------------
/PostgreSQL Summary Stats and Window Functions /3.Aggregate window functions and frames.sql:
--------------------------------------------------------------------------------
1 | -- Running totals of athlete medals
2 | WITH Athlete_Medals AS (
3 | SELECT
4 | Athlete, COUNT(*) AS Medals
5 | FROM Summer_Medals
6 | WHERE
7 | Country = 'USA' AND Medal = 'Gold'
8 | AND Year >= 2000
9 | GROUP BY Athlete)
10 |
11 | SELECT
12 | Athlete,
13 | Medals,
14 | SUM(Medals) OVER (ORDER BY Athlete ASC) AS Max_Medals
15 | FROM Athlete_Medals
16 | ORDER BY Athlete ASC;
17 |
18 | -- Maximum country medals by year
19 |
20 | WITH Country_Medals AS (
21 | SELECT
22 | Year, Country, COUNT(*) AS Medals
23 | FROM Summer_Medals
24 | WHERE
25 | Country IN ('CHN', 'KOR', 'JPN')
26 | AND Medal = 'Gold' AND Year >= 2000
27 | GROUP BY Year, Country)
28 |
29 | SELECT
30 | Year,
31 | Country,
32 | Medals,
33 | MAX(Medals) OVER (PARTITION BY Country ORDER BY Year ASC) AS Max_Medals
34 | FROM Country_Medals
35 | ORDER BY Country ASC, Year ASC;
36 |
37 | -- Minimum country medals by year
38 | WITH France_Medals AS (
39 | SELECT
40 | Year, COUNT(*) AS Medals
41 | FROM Summer_Medals
42 | WHERE
43 | Country = 'FRA'
44 | AND Medal = 'Gold' AND Year >= 2000
45 | GROUP BY Year)
46 |
47 | SELECT
48 | Year,
49 | Medals,
50 | MIN(Medals) OVER (ORDER BY Year ASC) AS Min_Medals
51 | FROM France_Medals
52 | ORDER BY Year ASC;
53 |
54 | /*
55 | -- Number of rows in a frame
56 | Q: How many rows does the following frame span?
57 | ROWS BETWEEN 3 PRECEDING AND 2 FOLLOWING
58 | A: 6
59 | */
60 |
61 | -- Moving maximum of Scandinavian athletes' medals
62 | WITH Scandinavian_Medals AS (
63 | SELECT
64 | Year, COUNT(*) AS Medals
65 | FROM Summer_Medals
66 | WHERE
67 | Country IN ('DEN', 'NOR', 'FIN', 'SWE', 'ISL')
68 | AND Medal = 'Gold'
69 | GROUP BY Year)
70 |
71 | SELECT
72 | Year,
73 | Medals,
74 | MAX(Medals) OVER (ORDER BY YEAR ASC ROWS BETWEEN CURRENT ROW AND 1 FOLLOWING ) AS Max_Medals
75 | FROM Scandinavian_Medals
76 | ORDER BY Year ASC;
77 |
78 | -- Moving maximum of Chinese athletes' medals
79 | WITH Chinese_Medals AS (
80 | SELECT
81 | Athlete, COUNT(*) AS Medals
82 | FROM Summer_Medals
83 | WHERE
84 | Country = 'CHN' AND Medal = 'Gold'
85 | AND Year >= 2000
86 | GROUP BY Athlete)
87 |
88 | SELECT
89 | Athlete,
90 | Medals,
91 | MAX(Medals) OVER (ORDER BY Athlete ASC ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS Max_Medals
92 | FROM Chinese_Medals
93 | ORDER BY Athlete ASC;
94 |
95 | /*
96 | -- Moving average's frame
97 | Q: If you want your moving average to cover the last 3 and current Olympic games, how would you define its frame?
98 | A: ROWS BETWEEN 3 PRECEDING AND CURRENT ROW
99 | */
100 |
101 | -- Moving average of Russian medals
102 | WITH Russian_Medals AS (
103 | SELECT
104 | Year, COUNT(*) AS Medals
105 | FROM Summer_Medals
106 | WHERE
107 | Country = 'RUS'
108 | AND Medal = 'Gold'
109 | AND Year >= 1980
110 | GROUP BY Year)
111 |
112 | SELECT
113 | Year, Medals,
114 | AVG(Medals) OVER
115 | (ORDER BY Year ASC ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS Medals_MA
116 | FROM Russian_Medals
117 | ORDER BY Year ASC;
118 |
119 | -- Moving total of countries' medals
120 | WITH Country_Medals AS (
121 | SELECT
122 | Year, Country, COUNT(*) AS Medals
123 | FROM Summer_Medals
124 | GROUP BY Year, Country)
125 |
126 | SELECT
127 | Year, Country, Medals,
128 | SUM(Medals) OVER
129 | (PARTITION BY Country
130 | ORDER BY Year ASC
131 | ROWS BETWEEN
132 | 2 PRECEDING AND CURRENT ROW) AS Medals_MA
133 | FROM Country_Medals
134 | ORDER BY Country ASC, Year ASC;
--------------------------------------------------------------------------------
/Joining Data in SQL/4) Subqueries.sql:
--------------------------------------------------------------------------------
1 | -- Subquery inside where
2 | -- (1)
3 |
4 | SELECT AVG(life_expectancy)
5 | FROM populations
6 | WHERE Year=2015;
7 |
8 | -- (2)
9 |
10 | SELECT *
11 | FROM populations
12 | WHERE life_expectancy > 1.15 *
13 | (SELECT AVG(life_expectancy)
14 | FROM populations
15 | WHERE year = 2015)
16 | AND year = 2015;
17 |
18 | -- Subquery inside where (2)
19 |
20 | SELECT cities.name, country_code, urbanarea_pop
21 | FROM cities
22 | WHERE cities.name IN
23 | (SELECT capital
24 | FRoM countries)
25 | ORDER BY urbanarea_pop DESC;
26 |
27 | -- Subquery inside select
28 |
29 | SELECT countries.name AS country,
30 | (SELECT COUNT(*)
31 | FROM cities
32 | WHERE countries.code = cities.country_code) AS cities_num
33 | FROM countries
34 | ORDER BY cities_num DESC, country
35 | LIMIT 9;
36 |
37 | -- Subquery inside from
38 | -- (1)
39 | SELECT code, COUNT(name) AS lang_num
40 | FROM languages
41 | GROUP BY code;
42 |
43 | -- (2)
44 |
45 | SELECT local_name, subquery.lang_num
46 | FROM countries,
47 | (SELECT code, COUNT(name) AS lang_num
48 | FROM languages
49 | GROUP BY code) AS subquery
50 | WHERE countries.code = subquery.code
51 | ORDER BY lang_num DESC;
52 |
53 | -- Advanced subquery
54 |
55 | -- (1)
56 |
57 | SELECT name, continent, inflation_rate
58 | FROM countries
59 | INNER JOIN economies
60 | USING (code)
61 | WHERE year = 2015;
62 |
63 | -- (2)
64 |
65 | SELECT MAX(inflation_rate) AS max_inf
66 | FROM (
67 | SELECT name, continent, inflation_rate
68 | FROM countries
69 | INNER JOIN economies
70 | USING (code)
71 | WHERE year = 2015) AS subquery
72 | GROUP BY continent;
73 |
74 | -- (3)
75 |
76 | SELECT name, continent, inflation_rate
77 | FROM countries
78 | INNER JOIN economies
79 | ON countries.code = economies.code
80 | WHERE year = 2015
81 | AND inflation_rate IN (
82 | SELECT MAX(inflation_rate) AS max_inf
83 | FROM (
84 | SELECT name, continent, inflation_rate
85 | FROM countries
86 | INNER JOIN economies
87 | ON countries.code = economies.code
88 | WHERE year = 2015) AS subquery
89 | GROUP BY continent);
90 |
91 | -- Subquery challenge
92 |
93 | SELECT code, inflation_rate, unemployment_rate
94 | FROM economies
95 | WHERE year = 2015 AND code NOT IN
96 | (SELECT code
97 | FROM countries
98 | WHERE (gov_form = 'Constitutional Monarchy' OR gov_form LIKE '%Republic'))
99 | ORDER BY inflation_rate;
100 |
101 | -- Subquery review
102 | -- Ans:- WHERE
103 |
104 | -- Final challenge
105 |
106 | SELECT DISTINCT c.name, e.total_investment, e.imports
107 | FROM countries AS c
108 | LEFT JOIN economies AS e
109 | ON (c.code = e.code AND c.code IN
110 | (SELECT code
111 | FROM languages
112 | WHERE official = 'true'))
113 | WHERE year = 2015 AND region = 'Central America'
114 | ORDER BY c.name;
115 |
116 | -- Final challenge (2)
117 |
118 | SELECT region, continent, AVG(fertility_rate) AS avg_fert_rate
119 | FROM countries AS c
120 | INNER JOIN populations AS p
121 | ON c.code = p.country_code
122 | WHERE year = 2015
123 | GROUP BY region, continent
124 | ORDER BY avg_fert_rate;
125 |
126 | -- Final challenge (3)
127 |
128 | SELECT name, country_code, city_proper_pop, metroarea_pop,
129 | city_proper_pop / metroarea_pop * 100 AS city_perc
130 | FROM cities
131 | WHERE name IN
132 | (SELECT capital
133 | FROM countries
134 | WHERE (continent = 'Europe'
135 | OR continent LIKE '%America'))
136 | AND metroarea_pop IS NOT NULL
137 | ORDER BY city_perc DESC
138 | LIMIT 10;
139 |
140 |
--------------------------------------------------------------------------------
/Intermediate SQL/2. Short and Simple Subqueries.sql:
--------------------------------------------------------------------------------
1 | -- Filtering using scalar subqueries
2 |
3 | -- (1)
4 | SELECT
5 | 3 * AVG(home_goal + away_goal)
6 | FROM matches_2013_2014;
7 |
8 | -- (2)
9 | SELECT
10 | date,
11 | home_goal,
12 | away_goal
13 | FROM matches_2013_2014
14 | WHERE (home_goal + away_goal) >
15 | (SELECT 3 * AVG(home_goal + away_goal)
16 | FROM matches_2013_2014);
17 |
18 | -- Filtering using a subquery with a list
19 | SELECT
20 | team_long_name,
21 | team_short_name
22 | FROM team
23 | WHERE team_api_id NOT IN
24 | (SELECT DISTINCT hometeam_ID FROM match);
25 |
26 | -- Filtering with more complex subquery conditions
27 | SELECT
28 | team_long_name,
29 | team_short_name
30 | FROM team
31 | WHERE team_api_id IN
32 | (SELECT hometeam_id
33 | FROM match
34 | WHERE home_goal >= 8);
35 |
36 | -- Joining Subqueries in FROM
37 |
38 | -- (1)
39 | SELECT
40 | country_id,
41 | id
42 | FROM match
43 | WHERE (home_goal + away_goal) >= 10;
44 |
45 | -- (2)
46 | SELECT
47 | c.name AS country_name,
48 | COUNT(sub.id) AS matches
49 | FROM country AS c
50 | INNER JOIN (SELECT country_id, id
51 | FROM match
52 | WHERE (home_goal + away_goal) >= 10 ) AS sub
53 | ON c.id = sub.country_id
54 | GROUP BY country_name;
55 |
56 | -- Building on Subqueries in FROM
57 | SELECT
58 | country,
59 | date,
60 | home_goal,
61 | away_goal
62 | FROM
63 | (SELECT c.name AS country,
64 | m.date,
65 | m.home_goal,
66 | m.away_goal,
67 | ( m.home_goal + m.away_goal) AS total_goals
68 | FROM match AS m
69 | LEFT JOIN country AS c
70 | ON m.country_id = c.id) AS subq
71 | WHERE total_goals >= 10;
72 |
73 | -- Add a subquery to the SELECT clause
74 | SELECT
75 | l.name AS league,
76 | ROUND(AVG(m.home_goal + m.away_goal), 2) AS avg_goals,
77 | (SELECT ROUND(AVG(home_goal + away_goal), 2)
78 | FROM match
79 | WHERE season = '2013/2014') AS overall_avg
80 | FROM league AS l
81 | LEFT JOIN match AS m
82 | ON l.country_id = m.country_id
83 | WHERE m.season = '2013/2014'
84 | GROUP BY l.name;
85 |
86 | -- Subqueries in Select for Calculations
87 | SELECT
88 | l.name AS league,
89 | ROUND(AVG(m.home_goal + m.away_goal),2) AS avg_goals,
90 | ROUND(AVG(m.home_goal + m.away_goal) -
91 | (SELECT AVG(home_goal + away_goal)
92 | FROM match
93 | WHERE season = '2013/2014'),2) AS diff
94 | FROM league AS l
95 | LEFT JOIN match AS m
96 | ON l.country_id = m.country_id
97 | WHERE m.season = '2013/2014'
98 | GROUP BY l.name;
99 |
100 | -- ALL the Subqueries EVERYWHERE
101 | SELECT
102 | m.stage,
103 | ROUND(AVG(m.home_goal + m.away_goal),2) AS avg_goals,
104 | ROUND((SELECT AVG(home_goal + away_goal)
105 | FROM match
106 | WHERE season = '2012/2013'),2) AS overall
107 | FROM match AS m
108 | WHERE m.season = '2012/2013'
109 | GROUP BY m.stage;
110 |
111 | -- Add a subquery in FROM
112 | SELECT
113 | s.stage,
114 | ROUND(s.avg_goals,2) AS avg_goals
115 | FROM
116 | (SELECT
117 | stage,
118 | AVG(home_goal + away_goal) AS avg_goals
119 | FROM match
120 | WHERE season = '2012/2013'
121 | GROUP BY stage) AS s
122 | WHERE
123 | s.avg_goals > (SELECT AVG(home_goal + away_goal)
124 | FROM match WHERE season = '2012/2013');
125 |
126 | -- Add a subquery in SELECT
127 | SELECT
128 | s.stage,
129 | ROUND(s.avg_goals,2) AS avg_goal,
130 | (SELECT AVG(home_goal + away_goal) FROM match WHERE season = '2012/2013') AS overall_avg
131 | FROM
132 | (SELECT
133 | stage,
134 | AVG(home_goal + away_goal) AS avg_goals
135 | FROM match
136 | WHERE season = '2012/2013'
137 | GROUP BY stage) AS s
138 | WHERE
139 | s.avg_goals > (SELECT AVG(home_goal + away_goal)
140 | FROM match WHERE season = '2012/2013');
--------------------------------------------------------------------------------
/PostgreSQL Summary Stats and Window Functions /4.Beyond Window Functions.sql:
--------------------------------------------------------------------------------
1 | -- A basic pivot
2 | CREATE EXTENSION IF NOT EXISTS tablefunc;
3 |
4 | SELECT * FROM CROSSTAB($$
5 | SELECT
6 | Gender, Year, Country
7 | FROM Summer_Medals
8 | WHERE
9 | Year IN (2008, 2012)
10 | AND Medal = 'Gold'
11 | AND Event = 'Pole Vault'
12 | ORDER By Gender ASC, Year ASC;
13 | $$) AS ct (Gender VARCHAR,
14 | Year VARCHAR,
15 | Country VARCHAR)
16 |
17 | ORDER BY Gender ASC;
18 |
19 | -- Pivoting with ranking
20 | -- (1)
21 | SELECT
22 | Country,
23 | Year,
24 | COUNT(*) AS Awards
25 | FROM Summer_Medals
26 | WHERE
27 | Country IN ('FRA', 'GBR', 'GER')
28 | AND Year IN (2004, 2008, 2012)
29 | AND Medal = 'Gold'
30 | GROUP BY Country, Year
31 | ORDER BY Country ASC, Year ASC
32 |
33 | -- (2)
34 | WITH Country_Awards AS (
35 | SELECT
36 | Country,
37 | Year,
38 | COUNT(*) AS Awards
39 | FROM Summer_Medals
40 | WHERE
41 | Country IN ('FRA', 'GBR', 'GER')
42 | AND Year IN (2004, 2008, 2012)
43 | AND Medal = 'Gold'
44 | GROUP BY Country, Year)
45 |
46 | SELECT
47 | Country,
48 | Year,
49 | RANK() OVER(PARTITION BY Year ORDER BY Awards) :: INTEGER AS rank
50 | FROM Country_Awards
51 | ORDER BY Country ASC, Year ASC;
52 |
53 | -- (3)
54 | CREATE EXTENSION IF NOT EXISTS tablefunc;
55 |
56 | SELECT * FROM CROSSTAB($$
57 | WITH Country_Awards AS (
58 | SELECT
59 | Country,
60 | Year,
61 | COUNT(*) AS Awards
62 | FROM Summer_Medals
63 | WHERE
64 | Country IN ('FRA', 'GBR', 'GER')
65 | AND Year IN (2004, 2008, 2012)
66 | AND Medal = 'Gold'
67 | GROUP BY Country, Year)
68 |
69 | SELECT
70 | Country,
71 | Year,
72 | RANK() OVER
73 | (PARTITION BY Year
74 | ORDER BY Awards DESC) :: INTEGER AS rank
75 | FROM Country_Awards
76 | ORDER BY Country ASC, Year ASC;
77 | $$) AS ct (Country VARCHAR,
78 | "2004" INTEGER,
79 | "2008" INTEGER,
80 | "2012" INTEGER)
81 |
82 | Order by Country ASC;
83 |
84 | -- Country-level subtotals
85 | SELECT
86 | Country,
87 | Gender,
88 | COUNT(*) AS Gold_Awards
89 | FROM Summer_Medals
90 | WHERE
91 | Year = 2004
92 | AND Medal = 'Gold'
93 | AND Country IN ('DEN', 'NOR', 'SWE')
94 | GROUP BY Country, ROLLUP(Gender)
95 | ORDER BY Country ASC, Gender ASC;
96 |
97 | -- All group-level subtotals
98 | SELECT
99 | Gender,
100 | Medal,
101 | COUNT(*) AS Awards
102 | FROM Summer_Medals
103 | WHERE
104 | Year = 2012
105 | AND Country = 'RUS'
106 | GROUP BY CUBE(Gender, Medal)
107 | ORDER BY Gender ASC, Medal ASC;
108 |
109 | -- Cleaning up results
110 | SELECT
111 | COALESCE(Country, 'All countries') AS Country,
112 | COALESCE(Gender, 'All genders') AS Gender,
113 | COUNT(*) AS Awards
114 | FROM Summer_Medals
115 | WHERE
116 | Year = 2004
117 | AND Medal = 'Gold'
118 | AND Country IN ('DEN', 'NOR', 'SWE')
119 | GROUP BY ROLLUP(Country, Gender)
120 | ORDER BY Country ASC, Gender ASC;
121 |
122 | -- Summarizing results
123 | -- (1)
124 | WITH Country_Medals AS (
125 | SELECT
126 | Country,
127 | COUNT(*) AS Medals
128 | FROM Summer_Medals
129 | WHERE Year = 2000
130 | AND Medal = 'Gold'
131 | GROUP BY Country)
132 |
133 | SELECT
134 | Country,
135 | RANK() OVER(ORDER BY Medals DESC) AS Rank
136 | FROM Country_Medals
137 | ORDER BY Rank ASC;
138 |
139 | -- (2)
140 | WITH Country_Medals AS (
141 | SELECT
142 | Country,
143 | COUNT(*) AS Medals
144 | FROM Summer_Medals
145 | WHERE Year = 2000
146 | AND Medal = 'Gold'
147 | GROUP BY Country),
148 |
149 | Country_Ranks AS (
150 | SELECT
151 | Country,
152 | RANK() OVER (ORDER BY Medals DESC) AS Rank
153 | FROM Country_Medals
154 | ORDER BY Rank ASC)
155 |
156 | SELECT STRING_AGG(Country,', ')
157 | FROM Country_Ranks
158 | -- Select only the top three ranks
159 | WHERE RANK <= 3;
--------------------------------------------------------------------------------
/Functions for Manipulating Data in PostgreSQL/2.Working with DATE-TIME Functions and Operators.sql:
--------------------------------------------------------------------------------
1 | -- Adding and subtracting date and time values
2 | -- (1)
3 | SELECT f.title, f.rental_duration,
4 | r.return_date - r.rental_date AS days_rented
5 | FROM film AS f
6 | INNER JOIN inventory AS i ON f.film_id = i.film_id
7 | INNER JOIN rental AS r ON i.inventory_id = r.inventory_id
8 | ORDER BY f.title;
9 |
10 | -- (2)
11 | SELECT f.title, f.rental_duration,
12 | AGE(r.return_date, r.rental_date) AS days_rented
13 | FROM film AS f
14 | INNER JOIN inventory AS i ON f.film_id = i.film_id
15 | INNER JOIN rental AS r ON i.inventory_id = r.inventory_id
16 | WHERE r.return_date IS NOT NULL
17 | ORDER BY f.title;
18 |
19 | -- INTERVAL arithmetic
20 | SELECT
21 | f.title,
22 | INTERVAL '1' day * f.rental_duration,
23 | r.return_date - r.rental_date AS days_rented
24 | FROM film AS f
25 | INNER JOIN inventory AS i ON f.film_id = i.film_id
26 | INNER JOIN rental AS r ON i.inventory_id = r.inventory_id
27 | WHERE r.return_date IS NOT NULL
28 | ORDER BY f.title;
29 |
30 | -- Calculating the expected return date
31 | SELECT
32 | f.title,
33 | r.rental_date,
34 | f.rental_duration,
35 | INTERVAL '1' day * f.rental_duration + r.rental_date AS expected_return_date,
36 | r.return_date
37 | FROM film AS f
38 | INNER JOIN inventory AS i ON f.film_id = i.film_id
39 | INNER JOIN rental AS r ON i.inventory_id = r.inventory_id
40 | ORDER BY f.title;
41 |
42 | -- Working with the current date and time
43 | -- (1)
44 | SELECT NOW();
45 |
46 | -- (2)
47 | SELECT CURRENT_DATE;
48 |
49 | -- (3)
50 | SELECT CAST( NOW() AS timestamp )
51 |
52 | -- (4)
53 | SELECT
54 | CURRENT_DATE,
55 | CAST( NOW() AS date )
56 |
57 | -- Manipulating the current date and time
58 | -- (1)
59 | SELECT
60 | CURRENT_TIMESTAMP::timestamp AS right_now;
61 |
62 | -- (2)
63 | SELECT
64 | CURRENT_TIMESTAMP::timestamp AS right_now,
65 | INTERVAL '5 ___' + CURRENT_TIMESTAMP AS five_days_from_now;
66 |
67 | -- (3)
68 | SELECT
69 | CURRENT_TIMESTAMP(0)::timestamp AS right_now,
70 | interval '5 days' + CURRENT_TIMESTAMP(0) AS five_days_from_now;
71 |
72 | -- Using EXTRACT
73 | -- (1)
74 | SELECT
75 | EXTRACT(dow FROM rental_date) AS dayofweek
76 | FROM rental
77 | LIMIT 100;
78 |
79 | -- (2)
80 | SELECT
81 | EXTRACT(dow FROM rental_date) AS dayofweek,
82 | COUNT(rental_id) as rentals
83 | FROM rental
84 | GROUP BY 1;
85 |
86 | -- Using DATE_TRUNC
87 | -- (1)
88 | SELECT DATE_TRUNC('Year', rental_date) AS rental_year
89 | FROM rental;
90 |
91 | -- (2)
92 | SELECT DATE_TRUNC('Month', rental_date) AS rental_month
93 | FROM rental;
94 |
95 | -- (3)
96 | SELECT DATE_TRUNC('Day', rental_date) AS rental_day
97 | FROM rental;
98 |
99 | -- (4)
100 | SELECT
101 | DATE_TRUNC('Day', rental_date) AS rental_day,
102 | COUNT(rental_id) AS rentals
103 | FROM rental
104 | GROUP BY 1;
105 |
106 | -- Putting it all together
107 | -- (1)
108 | SELECT
109 | EXTRACT(dow FROM rental_date) AS dayofweek,
110 | AGE(return_date, rental_date) AS rental_days
111 | FROM rental AS r
112 | WHERE
113 | rental_date BETWEEN CAST('2005-05-01' AS DATE)
114 | AND CAST('2005-05-01' AS DATE) + INTERVAL '90 day';
115 |
116 | -- (2)
117 | SELECT
118 | c.first_name || ' ' || c.last_name AS customer_name,
119 | f.title,
120 | r.rental_date,
121 | EXTRACT(dow FROM r.rental_date) AS dayofweek,
122 | AGE(r.return_date, r.rental_date) AS rental_days,
123 | CASE WHEN DATE_TRUNC('day', AGE(r.return_date, r.rental_date)) >
124 | f.rental_duration * INTERVAL '1' day
125 | THEN TRUE
126 | ELSE FALSE END AS past_due
127 | FROM
128 | film AS f
129 | INNER JOIN inventory AS i
130 | ON f.film_id = i.film_id
131 | INNER JOIN rental AS r
132 | ON i.inventory_id = r.inventory_id
133 | INNER JOIN customer AS c
134 | ON c.customer_id = r.customer_id
135 | WHERE
136 | r.rental_date BETWEEN CAST('2005-05-01' AS DATE)
137 | AND CAST('2005-05-01' AS DATE) + INTERVAL '90 day';
--------------------------------------------------------------------------------
/Intermediate SQL/4. Window Functions.sql:
--------------------------------------------------------------------------------
1 | -- The match is OVER
2 | SELECT
3 | m.id,
4 | c.name AS country,
5 | m.season,
6 | m.home_goal,
7 | m.away_goal,
8 | AVG(m.home_goal + m.away_goal) OVER() AS overall_avg
9 | FROM match AS m
10 | LEFT JOIN country AS c ON m.country_id = c.id;
11 |
12 |
13 | -- What's OVER here?
14 | SELECT
15 | l.name AS league,
16 | AVG(m.home_goal + m.away_goal) AS avg_goals,
17 | RANK() OVER(ORDER BY AVG(m.home_goal + m.away_goal)) AS league_rank
18 | FROM league AS l
19 | LEFT JOIN match AS m
20 | ON l.id = m.country_id
21 | WHERE m.season = '2011/2012'
22 | GROUP BY l.name
23 | ORDER BY league_rank;
24 |
25 |
26 | -- Flip OVER your results
27 | SELECT
28 | l.name AS league,
29 | AVG(m.home_goal + m.away_goal) AS avg_goals,
30 | RANK() OVER(ORDER BY AVG(m.home_goal + m.away_goal) DESC) AS league_rank
31 | FROM league AS l
32 | LEFT JOIN match AS m
33 | ON l.id = m.country_id
34 | WHERE m.season = '2011/2012'
35 | GROUP BY l.name
36 | ORDER BY league_rank;
37 |
38 |
39 | -- PARTITION BY a column
40 | SELECT
41 | date,
42 | season,
43 | home_goal,
44 | away_goal,
45 | CASE WHEN hometeam_id = 8673 THEN 'home'
46 | ELSE 'away' END AS warsaw_location,
47 | AVG(home_goal) OVER(PARTITION BY season) AS season_homeavg,
48 | AVG(away_goal) OVER(PARTITION BY season) AS season_awayavg
49 | FROM match
50 | WHERE
51 | hometeam_id = 8673
52 | OR awayteam_id = 8673
53 | ORDER BY (home_goal + away_goal) DESC;
54 |
55 |
56 | -- PARTITION BY multiple columns
57 | SELECT
58 | date,
59 | season,
60 | home_goal,
61 | away_goal,
62 | CASE WHEN hometeam_id = 8673 THEN 'home'
63 | ELSE 'away' END AS warsaw_location,
64 | AVG(home_goal) OVER(PARTITION BY season,
65 | EXTRACT(month FROM date)) AS season_mo_home,
66 | AVG(away_goal) OVER(PARTITION BY season,
67 | EXTRACT(month FROM date)) AS season_mo_away
68 | FROM match
69 | WHERE
70 | hometeam_id = 8673
71 | OR awayteam_id = 8673
72 | ORDER BY (home_goal + away_goal) DESC;
73 |
74 |
75 | -- Slide to the left
76 | SELECT
77 | date,
78 | home_goal,
79 | away_goal,
80 | SUM(home_goal) OVER(ORDER BY date
81 | ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS running_total,
82 | AVG(home_goal) OVER(ORDER BY date
83 | ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS running_avg
84 | FROM match
85 | WHERE
86 | hometeam_id = 9908
87 | AND season = '2011/2012';
88 |
89 |
90 | -- Slide to the right
91 | SELECT
92 | date,
93 | home_goal,
94 | away_goal,
95 | SUM(home_goal) OVER(ORDER BY date DESC
96 | ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) AS running_total,
97 | AVG(home_goal) OVER(ORDER BY date DESC
98 | ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) AS running_avg
99 | FROM match
100 | WHERE
101 | awayteam_id = 9908
102 | AND season = '2011/2012';
103 |
104 |
105 | -- Setting up the home team CTE
106 | SELECT
107 | m.id,
108 | t.team_long_name,
109 | CASE WHEN m.home_goal > m.away_goal THEN 'MU Win'
110 | WHEN m.home_goal < m.away_goal THEN 'MU Loss'
111 | ELSE 'Tie' END AS outcome
112 | FROM match AS m
113 | LEFT JOIN team AS t
114 | ON m.hometeam_id = t.team_api_id
115 | WHERE
116 | m.season = '2014/2015'
117 | AND t.team_long_name = 'Manchester United';
118 |
119 |
120 | -- Setting up the away team CTE
121 | SELECT
122 | m.id,
123 | t.team_long_name,
124 | CASE WHEN m.home_goal > m.away_goal THEN 'MU Loss'
125 | WHEN m.home_goal < m.away_goal THEN 'MU Win'
126 | ELSE 'Tie' END AS outcome
127 | FROM match AS m
128 | LEFT JOIN team AS t
129 | ON m.awayteam_id = t.team_api_id
130 | WHERE
131 | m.season = '2014/2015'
132 | AND t.team_long_name = 'Manchester United';
133 |
134 |
135 | -- Putting the CTEs together
136 | WITH home AS (
137 | SELECT m.id, t.team_long_name,
138 | CASE WHEN m.home_goal > m.away_goal THEN 'MU Win'
139 | WHEN m.home_goal < m.away_goal THEN 'MU Loss'
140 | ELSE 'Tie' END AS outcome
141 | FROM match AS m
142 | LEFT JOIN team AS t ON m.hometeam_id = t.team_api_id),
143 | away AS (
144 | SELECT m.id, t.team_long_name,
145 | CASE WHEN m.home_goal > m.away_goal THEN 'MU Win'
146 | WHEN m.home_goal < m.away_goal THEN 'MU Loss'
147 | ELSE 'Tie' END AS outcome
148 | FROM match AS m
149 | LEFT JOIN team AS t ON m.awayteam_id = t.team_api_id)
150 | SELECT DISTINCT
151 | m.date,
152 | home.team_long_name AS home_team,
153 | away.team_long_name AS away_team,
154 | m.home_goal,
155 | m.away_goal
156 | FROM match AS m
157 | LEFT JOIN home ON m.id = home.id
158 | LEFT JOIN away ON m.id = away.id
159 | WHERE m.season = '2014/2015'
160 | AND (home.team_long_name = 'Manchester United'
161 | OR away.team_long_name = 'Manchester United');
162 |
163 |
164 | -- Add a window function
165 | WITH home AS (
166 | SELECT m.id, t.team_long_name,
167 | CASE WHEN m.home_goal > m.away_goal THEN 'MU Win'
168 | WHEN m.home_goal < m.away_goal THEN 'MU Loss'
169 | ELSE 'Tie' END AS outcome
170 | FROM match AS m
171 | LEFT JOIN team AS t ON m.hometeam_id = t.team_api_id),
172 | away AS (
173 | SELECT m.id, t.team_long_name,
174 | CASE WHEN m.home_goal > m.away_goal THEN 'MU Loss'
175 | WHEN m.home_goal < m.away_goal THEN 'MU Win'
176 | ELSE 'Tie' END AS outcome
177 | FROM match AS m
178 | LEFT JOIN team AS t ON m.awayteam_id = t.team_api_id)
179 | SELECT DISTINCT
180 | m.date,
181 | home.team_long_name AS home_team,
182 | away.team_long_name AS away_team,
183 | m.home_goal, m.away_goal,
184 | RANK() OVER(ORDER BY ABS(home_goal - away_goal) DESC) as match_rank
185 | FROM match AS m
186 | LEFT JOIN home ON m.id = home.id
187 | LEFT JOIN AWAY ON m.id = away.id
188 | WHERE m.season = '2014/2015'
189 | AND ((home.team_long_name = 'Manchester United' AND home.outcome = 'MU Loss')
190 | OR (away.team_long_name = 'Manchester United' AND away.outcome = 'MU Loss'));
--------------------------------------------------------------------------------
/Intermediate SQL/3. Correlated Queries, Nested Queries, and Common Table Expressions.sql:
--------------------------------------------------------------------------------
1 | -- Basic Correlated Subqueries
2 | SELECT
3 | main.country_id,
4 | main.date,
5 | main.home_goal,
6 | main.away_goal
7 | FROM match AS main
8 | WHERE
9 | (home_goal + away_goal) >
10 | (SELECT AVG((sub.home_goal + sub.away_goal) * 3)
11 | FROM match AS sub
12 | -- Join the main query to the subquery in WHERE
13 | WHERE main.country_id = sub.country_id);
14 |
15 | -- Correlated subquery with multiple conditions
16 | SELECT
17 | main.country_id,
18 | main.date,
19 | main.home_goal,
20 | main.away_goal
21 | FROM match AS main
22 | WHERE
23 | (home_goal + away_goal) =
24 | (SELECT MAX(sub.home_goal + sub.away_goal)
25 | FROM match AS sub
26 | WHERE main.country_id = sub.country_id
27 | AND main.season = sub.season);
28 |
29 | -- Nested simple subqueries
30 | SELECT
31 | -- Select the season and max goals scored in a match
32 | season,
33 | MAX(home_goal + away_goal) AS max_goals,
34 | -- Select the overall max goals scored in a match
35 | (SELECT MAX(home_goal + away_goal) FROM match) AS overall_max_goals,
36 | -- Select the max number of goals scored in any match in July
37 | (SELECT MAX(home_goal + away_goal)
38 | FROM match
39 | WHERE id IN (
40 | SELECT id FROM match WHERE EXTRACT(MONTH FROM date) = 07)) AS july_max_goals
41 | FROM match
42 | GROUP BY season;
43 |
44 | -- Nest a subquery in FROM
45 |
46 | -- (1)
47 | SELECT
48 | country_id,
49 | season,
50 | id
51 | FROM match
52 | WHERE home_goal >= 5 OR away_goal >= 5;
53 |
54 | -- (2)
55 | SELECT
56 | country_id,
57 | season,
58 | COUNT(id) AS matches
59 | FROM ( SELECT
60 | country_id,
61 | season,
62 | id
63 | FROM match
64 | WHERE home_goal >= 5 OR away_goal >= 5) AS subquery
65 | GROUP BY country_id, season;
66 |
67 | -- (3)
68 | SELECT
69 | c.name AS country,
70 | AVG(c.id) AS avg_seasonal_high_scores
71 | FROM country AS c
72 | -- Left join outer_s to country
73 | LEFT JOIN (
74 | SELECT country_id, season,
75 | COUNT(id) AS matches
76 | FROM (
77 | SELECT country_id, season, id
78 | FROM match
79 | WHERE home_goal >= 5 OR away_goal >= 5) AS inner_s
80 | GROUP BY country_id, season) AS outer_s
81 | ON c.id = outer_s.country_id
82 | GROUP BY country;
83 |
84 | -- Clean up with CTEs
85 | WITH match_list AS (
86 | SELECT
87 | country_id,
88 | id
89 | FROM match
90 | WHERE (home_goal + away_goal) >= 10)
91 | SELECT
92 | l.name AS league,
93 | COUNT(match_list.id) AS matches
94 | FROM league AS l
95 | LEFT JOIN match_list ON l.id = match_list.country_id
96 | GROUP BY l.name;
97 |
98 | -- Organizing with CTEs
99 | WITH match_list AS
100 | ( SELECT
101 | l.name AS league,
102 | m.date,
103 | m.home_goal,
104 | m.away_goal,
105 | (m.home_goal + m.away_goal) AS total_goals
106 | FROM match AS m
107 | LEFT JOIN league as l ON m.country_id = l.id)
108 | SELECT league, date, home_goal, away_goal
109 | FROM match_list
110 | WHERE total_goals >= 10;
111 |
112 | -- CTEs with nested subqueries
113 | WITH match_lis t AS ( SELECT
114 | country_id,
115 | (home_goal + away_goal) AS goals
116 | FROM match
117 | WHERE id IN
118 | ( SELECT id
119 | FROM match
120 | WHERE season = '2013/2014' AND EXTRACT(MONTH FROM date) = 08)
121 | )
122 | SELECT
123 | l.name,
124 | AVG(match_list.goals)
125 | FROM league AS l
126 | LEFT JOIN match_list ON l.id = match_list.country_id
127 | GROUP BY l.name;
128 |
129 | -- Get team names with a subquery
130 |
131 | -- (1)
132 | SELECT
133 | m.id,
134 | t.team_long_name AS hometeam
135 | FROM match AS m
136 | LEFT JOIN team as t
137 | ON m.hometeam_id = team_api_id;
138 |
139 | -- (2)
140 | SELECT
141 | m.date,
142 | hometeam,
143 | awayteam,
144 | m.home_goal,
145 | m.away_goal
146 | FROM match AS m
147 | LEFT JOIN
148 | ( SELECT match.id, team.team_long_name AS hometeam
149 | FROM match
150 | LEFT JOIN team
151 | ON match.hometeam_id = team.team_api_id) AS home
152 |
153 | ON home.id = m.id
154 | LEFT JOIN
155 | ( SELECT match.id, team.team_long_name AS awayteam
156 | FROM match
157 | LEFT JOIN team
158 | -- Get the away team ID in the subquery
159 | ON match.awayteam_id = team.team_api_id) AS away
160 | ON away.id = m.id;
161 |
162 | -- Get team names with correlated subqueries
163 |
164 | -- (1)
165 | SELECT
166 | m.date,
167 | (SELECT team_long_name
168 | FROM team AS t
169 | WHERE t.team_api_id = m.hometeam_id) AS hometeam
170 | FROM match AS m;
171 |
172 | -- (2)
173 | SELECT
174 | m.date,
175 |
176 | (SELECT team_long_name
177 | FROM team AS t
178 | WHERE t.team_api_id = m.hometeam_id) AS hometeam,
179 |
180 | (SELECT team_long_name
181 | FROM team AS t
182 | WHERE t.team_api_id = m.awayteam_id) AS awayteam,
183 |
184 | m.home_goal,
185 |
186 | m.away_goal
187 |
188 | FROM match AS m;
189 |
190 | -- Get team names with CTEs 10
191 |
192 | -- (1)
193 | SELECT
194 | m.id,
195 | t.team_long_name AS hometeam
196 | FROM match AS m
197 | LEFT JOIN team AS t
198 | ON m.hometeam_id = t.team_api_id;
199 |
200 | -- (2)
201 | WITH home AS (
202 | SELECT m.id, t.team_long_name AS hometeam
203 | FROM match AS m
204 | LEFT JOIN team AS t
205 | ON m.hometeam_id = t.team_api_id)
206 | SELECT *
207 | FROM home;
208 |
209 | -- (3)
210 | WITH home AS
211 | ( SELECT m.id, m.date,
212 | t.team_long_name AS hometeam, m.home_goal
213 | FROM match AS m
214 | LEFT JOIN team AS t
215 | ON m.hometeam_id = t.team_api_id),
216 | away AS (
217 | SELECT m.id, m.date,
218 | t.team_long_name AS awayteam, m.away_goal
219 | FROM match AS m
220 | LEFT JOIN team AS t
221 | ON m.awayteam_id = t.team_api_id)
222 | SELECT
223 | home.date,
224 | home.hometeam,
225 | away.awayteam,
226 | home.home_goal,
227 | away.away_goal
228 | FROM home
229 | INNER JOIN away
230 | ON home.id = away.id;
--------------------------------------------------------------------------------
/Intermediate SQL/1. We'll Take The Case.sql:
--------------------------------------------------------------------------------
1 | -- Basic CASE statements
2 |
3 | -- (1)
4 | SELECT
5 | team_api_id,
6 | team_long_name
7 | FROM teams_germany
8 | WHERE team_long_name IN ( 'FC Schalke 04' , 'FC Bayern Munich');
9 |
10 | -- (2)
11 | SELECT
12 | CASE WHEN hometeam_id = 10189 THEN 'FC Schalke 04'
13 | WHEN hometeam_id = 9823 THEN 'FC Bayern Munich'
14 | ELSE 'Other' END AS home_team,
15 | COUNT(id) AS total_matches
16 | FROM matches_germany
17 | GROUP BY home_team;
18 |
19 | -- CASE statements comparing column values
20 |
21 | -- (1)
22 | SELECT date,
23 | CASE WHEN home_goal > away_goal THEN 'Home win!'
24 | WHEN home_goal < away_goal THEN 'Home loss :('
25 | ELSE 'Tie' END AS outcome
26 | FROM matches_spain;
27 |
28 | -- (2)
29 | SELECT
30 | m.date,
31 | t.team_long_name AS opponent,
32 | CASE WHEN m.home_goal > away_goal THEN 'Home win!'
33 | WHEN m.home_goal < away_goal THEN 'Home loss :('
34 | ELSE 'Tie' END AS outcome
35 | FROM matches_spain AS m
36 | LEFT JOIN teams_spain AS t
37 | ON m.awayteam_id = t.team_api_id;
38 |
39 | -- (3)
40 | SELECT
41 | m.date,
42 | t.team_long_name AS opponent,
43 | CASE WHEN m.home_goal > m.away_goal THEN 'Barcelona win!'
44 | WHEN m.home_goal < m.away_goal THEN 'Barcelona loss :('
45 | ELSE 'Tie' END AS outcome
46 | FROM matches_spain AS m
47 | LEFT JOIN teams_spain AS t
48 | ON m.awayteam_id = t.team_api_id
49 | WHERE m.hometeam_id = 8634;
50 |
51 | -- CASE statements comparing two column values part 2
52 | SELECT
53 | m.date,
54 | t.team_long_name AS opponent,
55 | CASE WHEN m.home_goal < m.away_goal THEN 'Barcelona win!'
56 | WHEN m.home_goal > m.away_goal THEN 'Barcelona loss :('
57 | ELSE 'Tie' END AS outcome
58 | FROM matches_spain AS m
59 | LEFT JOIN teams_spain AS t
60 | ON m.hometeam_id = t.team_api_id
61 | WHERE m.awayteam_id = 8634;
62 |
63 | -- In CASE of rivalry
64 |
65 | -- (1)
66 | SELECT
67 | date,
68 | CASE WHEN hometeam_id = 8634 THEN 'FC Barcelona'
69 | ELSE 'Real Madrid CF' END AS home,
70 | CASE WHEN awayteam_id = 8634 THEN 'FC Barcelona'
71 | ELSE 'Real Madrid CF' END AS away
72 | FROM matches_spain
73 | WHERE (awayteam_id = 8634 OR hometeam_id = 8634)
74 | AND (awayteam_id = 8633 OR hometeam_id = 8633);
75 |
76 | -- (2)
77 | SELECT
78 | date,
79 | CASE WHEN hometeam_id = 8634 THEN 'FC Barcelona'
80 | ELSE 'Real Madrid CF' END AS home,
81 | CASE WHEN awayteam_id = 8634 THEN 'FC Barcelona'
82 | ELSE 'Real Madrid CF' END AS away,
83 | CASE WHEN home_goal > away_goal AND hometeam_id = 8634 THEN 'Barcelona win!'
84 | WHEN home_goal > away_goal AND hometeam_id = 8633 THEN 'Real Madrid win!'
85 | WHEN home_goal < away_goal AND awayteam_id = 8634 THEN 'Barcelona win!'
86 | WHEN home_goal < away_goal AND awayteam_id = 8633 THEN 'Real Madrid win!'
87 | ELSE 'Tie!' END AS outcome
88 | FROM matches_spain
89 | WHERE (awayteam_id = 8634 OR hometeam_id = 8634)
90 | AND (awayteam_id = 8633 OR hometeam_id = 8633);
91 |
92 | -- Filtering your CASE statement
93 |
94 | -- (1)
95 | SELECT
96 | team_long_name,
97 | team_api_id
98 | FROM teams_italy
99 | WHERE team_long_name = 'Bologna';
100 |
101 | -- (2)
102 | SELECT
103 | season,
104 | date,
105 | CASE WHEN hometeam_id = 9857 AND home_goal > away_goal THEN 'Bologna Win'
106 | WHEN awayteam_id = 9857 AND away_goal > home_goal THEN 'Bologna Win'
107 | END AS outcome
108 | FROM matches_italy;
109 |
110 | -- (3)
111 | SELECT
112 | season,
113 | date,
114 | home_goal,
115 | away_goal
116 | FROM matches_italy
117 | WHERE
118 | CASE WHEN hometeam_id = 9857 AND home_goal > away_goal THEN 'Bologna Win'
119 | WHEN awayteam_id = 9857 AND away_goal > home_goal THEN 'Bologna Win'
120 | END IS NOT NULL;
121 |
122 | -- COUNT using CASE WHEN
123 |
124 | -- (1)
125 | SELECT
126 | c.name AS country,
127 | COUNT(CASE WHEN m.season = '2012/2013'
128 | THEN m.id ELSE NULL END) AS matches_2012_2013
129 | FROM country AS c
130 | LEFT JOIN match AS m
131 | ON c.id = m.country_id
132 | GROUP BY c.name;
133 |
134 | -- (2)
135 | SELECT
136 | c.name AS country,
137 | COUNT(CASE WHEN m.season = '2012/2013' THEN m.id END) AS matches_2012_2013,
138 | COUNT(CASE WHEN m.season = '2013/2014' THEN m.id END) AS matches_2013_2014,
139 | COUNT(CASE WHEN m.season = '2014/2015' THEN m.id END) AS matches_2014_2015
140 | FROM country AS c
141 | LEFT JOIN match AS m
142 | ON c.id = m.country_id
143 | GROUP BY c.name;
144 |
145 | -- COUNT and CASE WHEN with multiple conditions
146 | SELECT
147 | c.name AS country,
148 | SUM(CASE WHEN m.season = '2012/2013' AND m.home_goal > m.away_goal
149 | THEN 1 ELSE 0 END) AS matches_2012_2013,
150 | SUM(CASE WHEN m.season = '2013/2014' AND m.home_goal > m.away_goal
151 | THEN 1 ELSE 0 END) AS matches_2013_2014,
152 | SUM(CASE WHEN m.season = '2014/2015' AND m.home_goal > m.away_goal
153 | THEN 1 ELSE 0 END) AS matches_2014_2015
154 | FROM country AS c
155 | LEFT JOIN match AS m
156 | ON c.id = m.country_id
157 | GROUP BY c.name;
158 |
159 | -- Calculating percent with CASE and AVG
160 |
161 | -- (1)
162 | SELECT
163 | c.name AS country,
164 | COUNT(CASE WHEN m.home_goal > m.away_goal THEN m.id
165 | END) AS home_wins,
166 | COUNT(CASE WHEN m.home_goal < m.away_goal THEN m.id
167 | END) AS away_wins,
168 | COUNT(CASE WHEN m.home_goal = m.away_goal THEN m.id
169 | END) AS ties
170 | FROM country AS c
171 | LEFT JOIN matches AS m
172 | ON c.id = m.country_id
173 | GROUP BY country;
174 |
175 | -- (2)
176 | SELECT
177 | c.name AS country,
178 | AVG(CASE WHEN m.season= '2013/2014' AND m.home_goal = m.away_goal THEN 1
179 | WHEN m.season='2013/2014' AND m.home_goal != m.away_goal THEN 0
180 | END) AS ties_2013_2014,
181 | AVG(CASE WHEN m.season='2014/2015' AND m.home_goal = m.away_goal THEN 1
182 | WHEN m.season='2014/2015' AND m.home_goal != m.away_goal THEN 0
183 | END) AS ties_2014_2015
184 | FROM country AS c
185 | LEFT JOIN matches AS m
186 | ON c.id = m.country_id
187 | GROUP BY country;
188 |
189 | -- (3)
190 | SELECT
191 | c.name AS country,
192 | ROUND(AVG(CASE WHEN m.season='2013/2014' AND m.home_goal = m.away_goal THEN 1
193 | WHEN m.season='2013/2014' AND m.home_goal != m.away_goal THEN 0
194 | END),2) AS pct_ties_2013_2014,
195 | ROUND(AVG(CASE WHEN m.season='2014/2015' AND m.home_goal = m.away_goal THEN 1
196 | WHEN m.season='2014/2015' AND m.home_goal != m.away_goal THEN 0
197 | END),2) AS pct_ties_2014_2015
198 | FROM country AS c
199 | LEFT JOIN matches AS m
200 | ON c.id = m.country_id
201 | GROUP BY country;
--------------------------------------------------------------------------------