0% found this document useful (0 votes)
6 views

All-sql-cheat-sheet-a4

The document provides an overview of SQL, including its use for querying databases, filtering output, and joining multiple tables. It covers various SQL operations such as comparison operators, text operators, and aggregate functions, along with examples of queries. Additionally, it explains advanced concepts like window functions, subqueries, and set operations.
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
6 views

All-sql-cheat-sheet-a4

The document provides an overview of SQL, including its use for querying databases, filtering output, and joining multiple tables. It covers various SQL operations such as comparison operators, text operators, and aggregate functions, along with examples of queries. Additionally, it explains advanced concepts like window functions, subqueries, and set operations.
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 13

SQL FILTERING THE OUTPUT QUERYING MULTIPLE TABLES

SQL, or Structured Query Language, is a language to


talk to databases. It allows you to select specific COMPARISON OPERATORS INNER JOIN FULL JOIN
data and to build complex reports. Today, SQL is a Fetch names of cities that have a rating above JOIN (or explicitly INNER JOIN) returns rows FULL JOIN(or explicitly FULL OUTER JOIN) returns all
universal language of data. It is used in practically 3: that have matching values in both tables. rows from both tables – if there's no matching row in
all technologies that process data. the second table, NULLs are returned.
SELECT name
SELECT city.name, country.name SELECT city.name, country.name
SAMPLE DATA FROM city
WHERE rating > 3; FROM city FROM city
COUNTRY [INNER] JOIN country FULL [OUTER] JOIN country
id name population area ON city.country_id = country.id; ON city.country_id = country.id;
1 France 66600000 640680
Fetch names of cities that are neither Berlin CITY COUNTRY
2 Germany 80700000 357000 id name country_id id name
... ... ... ... nor Madrid:
1 Paris 1 1 France
CITY SELECT name 2 Berlin 2 2 Germany
CITY COUNTRY 3 Warsaw 4 NULL NULL
id name country_id population rating FROM city id name country_id id name NULL NULL NULL 3 Iceland
WHERE name != 'Berlin' 1 Paris 1 1 France
AND name != 'Madrid'; 2 Berlin 2 2 Germany
1 Paris 1 2243000 5 3 Warsaw 4 3 Iceland
2 Berlin 2 3460000 3
... ... ... ... ..
. TEXT OPERATORS
Fetch names of cities that start with a 'P' or end
QUERYING SINGLE TABLE with an 's':
LEFT JOIN CROSS JOIN
Fetch all columns from the country table: SELECT name
ON ci.country_id = co.id; FROM city SELECT name FROM
SELECT * WHERE name LIKE 'P%' city
FROM country; OR name LIKE '%s'; WHERE country_id IN (1, 4, 7, 8);
Fetch id and name columns from the
city table:
Fetch names of cities that start with any letter
SELECT id, name followed by 'ublin' (like Dublin in Ireland or Lublin
FROM city; in Poland):
Fetch city names sorted by the rating SELECT name
column in the default ASCending order: FROM city
WHERE name LIKE '_ublin';
SELECT name
FROM city
ORDER BY rating [ASC];
OTHER OPERATORS
Fetch city names sorted by the rating Fetch names of cities that have a population
column in the DESCending order:
between 500K and 5M:
SELECT name
SELECT name
FROM city
FROM city
ORDER BY rating DESC;
WHERE population BETWEEN 500000 AND
5000000;
ALIASES
COLUMNS Fetch names of cities that don't miss a rating value:
SELECT name AS city_name SELECT name
FROM city; FROM city
WHERE rating IS NOT NULL;
TABLES
SELECT co.name, ci.name
FROM city AS ci Fetch names of cities that are in countries with IDs 1,
JOIN country AS co 4, 7, or 8:
LEFT JOIN returns all rows from the left CROSS JOIN returns all possible combinations of
table with corresponding rows from the rows from both tables. There are two syntaxes
right table. If there's no matching row, available.
NULLs are returned as values from the
second table. SELECT city.name, country.name
FROM city
SELECT city.name, CROSS JOIN country;
country.name FROM city
LEFT JOIN country SELECT city.name, country.name
ON city.country_id = country.id; FROM city, country;
CITY COUNTRY
CITY COUNTRY id name country_id id name
id name country_id id name 1 Paris 1 1 France
1 Paris 1 1 France 1 Paris 1 2 Germany
2 Berlin 2 2 Germany 2 Berlin 2 1 France
3 Warsaw 4 NULL NULL 2 Berlin 2 2 Germany

RIGHT JOIN NATURAL JOIN


RIGHT JOIN returns all rows from the will join tables by all columns with
NATURAL JOIN
right table with corresponding rows the same name.
from the left table. If there's no
matching row, NULLs are returned as SELECT city.name, country.name
values from the left table. FROM city
NATURAL JOIN country;
SELECT city.name, CITY COUNTRY
country.name FROM city country_id id name name id
RIGHT JOIN country 6 6 San Marino San Marino 6
7 7 Vatican City Vatican City 7
ON city.country_id = country.id; 5 9 Greece Greece 9
10 11 Monaco Monaco 10
CITY COUNTRY
NATURAL JOINused these columns to id name country_id id name
match rows: city.id, city.name, 1 Paris 1 1 France
country.id, country.name NATURAL JOIN is 2 Berlin 2 2 Germany
very rarely used in practice. NULL NULL NULL 3 Iceland
AGGREGATION AND GROUPING SUBQUERIES SET OPERATIONS
GROUP BY groups together rows that have the same values in
specified columns. It computes summaries (aggregates) for each A subquery is a query that is nested inside another query, or inside Set operations are used to combine the results of two or more
unique combination of values. another subquery. There are different types of subqueries. queries into a single result. The combined queries must return the
same number of columns and compatible data types. The names of
SINGLE VALUE the corresponding columns can be different.

CITY The simplest subquery returns exactly one column and exactly one
id name country_id row. It can be used with comparison operators =, <, <=, >, or >=. CYCLING SKATING
1 Paris 1 id name country id name country
101 Marseille 1 CITY
This 102
query findsLyon 1 the same
cities with rating as country_id
Paris:
1
count
3
1 YK DE 1 YK DE
2 Berlin 2 2 ZG DE 2 DF DE
103 Hamburg 2 2 3 SELECT name FROM city 3 AK PL
4 2 3 WT PL
104 Munich 2 WHERE rating = ( ... ... ... ... ... ...
3 Warsaw 4
SELECT
105 Cracow 4
rating FROM
city UNION
WHERE name = 'Paris'
AGGREGATE FUNCTIONS ); UNION combines the results of two result sets and removes duplicates.
• avg(expr) − average value for rows within the group UNION ALL doesn't remove duplicate rows.
MULTIPLE VALUES
• count(expr) − count of values for rows within the group This query displays German cyclists together with German skaters:
A subquery can also return multiple columns or multiple rows. Such
• max(expr) − maximum value within the group SELECT name
subqueries can be used with operators IN, EXISTS, ALL, or ANY.
FROM cycling
• min(expr) − minimum value within the group This query finds cities in countries that have a population above 20M: WHERE country = 'DE'
• sum(expr) − sum of values within the group SELECT name UNION / UNION ALL
FROM city SELECT name
EXAMPLE QUERIES WHERE country_id IN ( FROM skating
Find out the number of cities: SELECT country_id WHERE country = 'DE';
SELECT COUNT(*) FROM country
FROM city; WHERE population > 20000000 INTERSECT
);
INTERSECT returns only rows that appear in both result sets.
Find out the number of cities with non-null ratings:
CORRELATED This query displays German cyclists who are also German skaters at the
SELECT COUNT(rating)
A correlated subquery refers to the tables introduced in the outer query. A same time:
FROM city;
correlated subquery depends on the outer query. It cannot be run SELECT name
Find out the number of distinctive country values: independently from the outer query. FROM cycling
SELECT COUNT(DISTINCT country_id) This query finds cities with a population greater than the average WHERE country = 'DE'
FROM city; population in the country: INTERSECT
SELECT * SELECT name
Find out the smallest and the greatest country populations: FROM city main_city FROM skating
WHERE population > ( WHERE country = 'DE';
SELECT MIN(population), MAX(population)
FROM country; SELECT
AVG(population) FROM EXCEPT
Find out the total population of cities in respective countries: city average_city
EXCEPT returns only the rows that appear in the first result set but
SELECT country_id, SUM(population) WHERE average_city.country_id = main_city.country_id do not appear in the second result set.
);
FROM city This query displays German cyclists unless they are also German
GROUP BY country_id; skaters at the same time:
This query finds countries that have at least one city:
SELECT name SELECT name
Find out the average rating for cities in respective countries if the
FROM country FROM cycling
average is above 3.0:
WHERE EXISTS ( WHERE country = 'DE'
SELECT country_id, AVG(rating) EXCEPT / MINUS
SELECT *
FROM city FROM city SELECT name
GROUP BY country_id WHERE country_id = country.id FROM skating
HAVING AVG(rating) > ); WHERE country = 'DE';
3.0;
WINDOW FUNCTIONS PARTITION BY ORDER BY
compute their result based on a sliding AGGREGATE FUNCTIONS VS. WINDOW
FUNCTIONS divides rows into multiple groups, called specifies the order of rows in each partition to
window frame, a set of rows that are
partitions, to which the window function is which the window function is applied.
somehow related to the current row. unlike aggregate functions, window functions do not
applied. PARTITION BY city ORDER BY month
collapse rows.
PARTITION BY city sold city month sold city month
month city sold month city sold 200 Rome 1 300 Paris 1
1 Rome 200 500 Paris 2 500 Paris 2
Aggregate Window 1 Paris
100 Londo 1 200 Rome 1
current row 2 Paris 500 2 Paris sum
Functions Functions 1 Londo 100 n 300 Rome 2
∑ 1 Rome 300 800 300 Paris 1
n 400 Rome 3
2 Rome 500 800 300 Rome 2 100 Londo 1
1 Paris 300
∑ 3 Rome 200 900 400 Londo 2 n
2 Rome 300
2 Londo 400 1 Londo 300 900 n 400 Londo 2
∑ ∑ n n 400 900 400 Rome 3 n
2
3 Rome 400 100 500
SYNTAX Default ORDER BY: with no ORDER BY clause, the
Default Partition: with no PARTITION BY clause, the order of rows within each partition is arbitrary.
entire result set is the partition.
SELECT city, month,

WINDOW FRAME
SELECT <column_1>, <column_2>,
sum(sold) OVER ( ⏴window_function>() OVER ( is a set of rows that are somehow related to the current row. The window frame is evaluated separately
PARTITION BY city PARTITION BY <...> within each partition.
ORDER BY month ORDER BY <...>
RANGE UNBOUNDED PRECEDING) ⏴window_frame>) ROWS | RANGE | GROUPS BETWEEN lower_bound AND upper_bound
total <window_column_alias>
PARTITION UNBOUNDED
FROM sales; FROM <table_name>; PRECEDING The bounds can be any of the five options:
N
PRECEDING ∙ UNBOUNDED PRECEDING
N ROWS
Named Window Definition ∙ n PRECEDING
CURRENT ∙ CURRENT ROW
M ROWS
ROW ∙ n FOLLOWING
SELECT country, city, SELECT <column_1>, <column_2>, ∙ UNBOUNDED FOLLOWING
rank() OVER ⏴window_function>() OVER M UNBOUNDE
country_sold_avg FOLLOWING D
⏴window_name> FOLLOWIN The lower_bound must be BEFORE the upper_bound
FROM sales FROM <table_name> G
WHERE month BETWEEN 1 AND 6 WHERE <...>
GROUP BY country, city GROUP BY <...>
HAVING sum(sold) > 10000 ROWS BETWEEN 1 PRECEDING RANGE BETWEEN 1 PRECEDING GROUPS BETWEEN 1 PRECEDING
HAVING <...> AND 1 FOLLOWING AND 1 FOLLOWING AND 1 FOLLOWING
WINDOW country_sold_avg WINDOW ⏴window_name> AS
AS ( (
PARTITION BY country city sold month city sold month city sold month
PARTITION BY <...> Paris 300 1 Paris 300 1 Paris 300 1
ORDER BY avg(sold) DESC) ORDER BY <...> Rome 200 1 Rome 200 1 Rome 200 1
ORDER BY country, city; ⏴window_frame>) Paris 500 2 Paris 500 2 Paris 500 2
curren Rome 100 4 curren Rome 100 4 curren Rome 100 4
ORDER BY <...>; t
Paris 200 4
t
Paris 200 4
t
Paris 200 4
ro ro ro
w Paris 300 5 w Paris 300 5 w Paris 300 5
Rome 200 5 Rome 200 5 Rome 200 5
Londo 200 5 Londo 200 5 Londo 200 5
PARTITION BY, ORDER BY, and window frame definition are all optional. n n n
London 100 6 London 100 6 London 100 6
Rome 300 6 Rome 300 6 Rome 300 6

LOGICAL ORDER OF OPERATIONS IN 1 row before the current values in the range between 3 and 5 1 group before the current row and 1
SQL row and 1 row after the
current row
ORDER BY must contain a single group after the current row
regardless of the value
expression
5. HAVING 10. ORDER BY
1. FROM, JOIN 6. window functions 7. SELECT 11. OFFSET
2. WHERE 8. DISTINCT 12. LIMIT/FETCH/TOP
3. GROUP BY 9. UNION/INTERSECT/EXCEPT
4. aggregate functions
If ORDER BY is specified, then the frame is
RANGE BETWEEN UNBOUNDED PRECEDING
As of 2020, GROUPS is
AND CURRENT ROW.
only supported in n PRECEDING
PostgreSQL 11 and up. CURRENT ROW BETWEEN CURRENT ROW AND CURRENT ROW
BETWEEN n PRECEDING AND DEFAULT WINDOW FRAME
CURRENT ROW
ABBREVIATIONS
You can use window functions in SELECT and ORDER BY. However, you can’t put window functions Without ORDER BY, the frame specification
anywhere in the FROM, WHERE, GROUP BY, or HAVING clauses. nAbbreviation
FOLLOWING Meaning
BETWEEN AND CURRENT ROW AND n FOLLOWING is ROWS BETWEEN UNBOUNDED PRECEDING
UNBOUNDED PRECEDING BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
UNBOUNDED FOLLOWING BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING AND UNBOUNDED FOLLOWING.
LIST OF WINDOW
RANKING FUNCTIONS DISTRIBUTION FUNCTIONS
FUNCTIONS
∙ row_number() − unique number for each row within partition, with ∙ percent_rank() − the percentile ranking number of a row—a value in
Aggregate Functions different numbers for tied values [0, 1] interval: (rank - 1) / (total number of rows - 1)
∙ rank() − ranking within partition, with gaps and same ranking for tied ∙ cume_dist() − the cumulative distribution of a value within a group of values, i.e.,
∙ avg()
values the number of rows with values less than or equal to the current row’s value
∙ count() divided by the total number of rows; a value in (0, 1] interval
∙ dense_rank() − ranking within partition, with no gaps and same ranking for
∙ max() tied values
∙ min() row_number rank dense_rank
city price over(order by price) percent_rank() OVER(ORDER BY sold) cume_dist() OVER(ORDER BY sold)
∙ sum() Paris 7 1 1 1 city sold cume_dist
Rome 7 2 1 1 city sold percent_ran Paris 100 0.2
Ranking k
London 8.5 3 3 2 Berlin 150 0.4
Paris 100 0
Functions Berlin 8.5 4 3 2 Rome 200 0.8
Berlin 150 0.25
Moscow 9 5 5 3 Moscow 200 0.8
∙ row_number() Rome 200 0.5
Madrid 10 6 6 4 without this row 50% of values are less than this row’s London 300 1 80% of values are
Moscow 200 0.5
Oslo 10 7 6 4 value less than or
∙ rank() London 300 1
equal to this
∙ dense_rank() one

Distribution
ORDER BY and Window Frame: rank() and dense_rank() require ORDER BY and Window Frame: Distribution functions require ORDER BY. They do not
Functions ORDER BY, but row_number() does not require ORDER BY. Ranking accept window frame definition (ROWS, RANGE, GROUPS).
∙ percent_rank() functions do not accept window frame definition (ROWS, RANGE, GROUPS).
∙ cume_dist()
Analytic Functions ANALYTIC FUNCTIONS ∙ first_value(expr) − the value for the first row within the window frame
∙ lead() ∙ lead(expr, offset, default) − the value for the row offset rows after the current; offset ∙ last_value(expr) − the value for the last row within the window frame
∙ lag() and
∙ ntile() default are optional; default values: offset = 1, default = NULL
∙ first_value() ∙ lag(expr, offset, default) − the value for the row offset rows before the current; offset first_value(sold) OVER last_value(sold) OVER
∙ last_value() and (PARTITION BY city ORDER BY month) (PARTITION BY city ORDER BY month
RANGE BETWEEN UNBOUNDED
default are optional; default values: offset = 1, default = NULL PRECEDING

∙ nth_value() lead(sold) OVER(ORDER BY month) lag(sold) OVER(ORDER BY month) city month sold first_value AND UNBOUNDED FOLLOWING)
Paris 1 500 500
month sold month sold Paris 2 300 500 city month sold last_value
1 500 300 1 500 Paris 3 400 500 Paris 1 500 400
NULL
2 300 400 2 300 Rome 2 200 200 Paris 2 300 400
order by
order by

500
AGGREGATE 3 400 Rome 3 300 200 Paris 3 400 400
month

3 400 100
month

300
4 100 500 4 100 Rome 4 500 200 Rome 2 200 500
FUNCTIONS 5 500 NULL 5 500
400
Rome 3 300 500
100
Rome 4 500 500
∙ avg(expr) − average value
for rows within the lead(sold, 2, 0) OVER(ORDER BY lag(sold, 2, 0) OVER(ORDER BY
window frame month) month) Note: You usually want to use RANGE BETWEEN
month sold month sold
UNBOUNDED PRECEDING AND UNBOUNDED
offset=
1 500 1 500
∙ count(expr) − count of 2 300 400 2 300 0 FOLLOWING with last_value(). With the
order by
order by

3 400 2 default
month

3 400 100 0
month

values for rows within the 4 100


4 100 500 500 window frame for ORDER BY, RANGE
window frame 5 500
offset=

5 500 0 300 UNBOUNDED PRECEDING, last_value()


0 400 returns the value for the current row.
2

∙ max(expr) − maximum
value within the window
frame

∙ min(expr) − minimum ∙ ntile(n) − divide rows within a partition as equally as possible into n groups, and assign
value within the each row its group number.
window frame ORDER BY and Window Frame: Aggregate functions do not require an ORDER
BY. They accept window frame definition (ROWS, RANGE, GROUPS). ntile(3)
city sold
∙ sum(expr) − sum of values Rome 100 1
within the window frame Paris 1001 1 1
London 200 1
Moscow 200 2
Berlin 200 2
Madrid 300 2
Oslo 300 3
2 ORDER BY ∙ nth_value(expr, n) 2− the value for the n-th row within the window frame; n must be
and an integer
Window nth_value(sold, 2) OVER
Frame: (PARTITION BY city 3ORDER BY
ntile(),
month RANGE BETWEEN UNBOUNDED
lead(),
PRECEDING AND UNBOUNDED city month sold nth_value
and lag()
FOLLOWING) Paris 1 500 300
require an
ORDER BY. Paris 2 300 300
They do Paris 3 400 300
Rome 2 200 300
not accept
Rome 3 300 300
window Rome 4 500 300
frame
definition ORDER BY and Window Rome 5 300 300
Frame: first_value(), London 1 100 NULL
3
last_value(), and
RANGE, nth_value() do not require
GROUPS). an ORDER BY. They accept
window frame definition
(ROWS, RANGE, GROUPS).
JOINING TABLES LEFT JOIN
JOIN combines data from two tables.
LEFT JOIN returns all rows from the left table with matching rows from the right table. Rows without a
TOY CAT match are filled with NULLs. LEFT JOIN is also called LEFT OUTER JOIN.
toy_id toy_name cat_id cat_id cat_name SELECT * toy_id toy_name cat_id cat_id cat_name
1 ball 3 1 Kitty 5 ball 1 1 Kitty
2 spring NULL 2 Hugo FROM toy
3 mouse 1 1 Kitty
3 mouse 1 3 Sam LEFT JOIN cat 1 ball 3 3 Sam
4 mouse 4 4 Misty ON toy.cat_id = cat.cat_id; 4 mouse 4 4 Misty
5 ball 1 2 spring NULL NULL NULL
whole left
JOIN typically combines rows with equal values for the specified columns. Usually, one table contains table
a primary key, which is a column or columns that uniquely identify rows in the table (the cat_id
column in the cat table).
The other table has a column or columns that refer to the primary key columns in the first table (the
cat_id column in the toy table). Such columns are foreign keys. The JOIN condition is the equality RIGHT JOIN
between the primary key columns in one table and columns referring to them in the other table. RIGHT JOIN returns all rows from the right table with matching rows from the left table. Rows
without a match are filled with NULLs. RIGHT JOIN is also called RIGHT OUTER JOIN.
JOIN SELECT * toy_id toy_name cat_id cat_id cat_name
FROM toy 5 ball 1 1 Kitty
JOIN returns all rows that match the ON condition. JOIN is also called INNER 3 mouse 1 1 Kitty
RIGHT JOIN cat NULL NULL NULL 2 Hugo
JOIN. SELECT * toy_id toy_name cat_id cat_id cat_name ON toy.cat_id = cat.cat_id; 1 ball 3 3 Sam
FROM toy 5 ball 1 1 Kitty 4 mouse 4 4 Misty
3 mouse 1 1 Kitty whole ht table
JOIN cat 1 ball 3 3 Sam rig
ON toy.cat_id = cat.cat_id; 4 mouse 4 4 Misty

There is also another, older syntax, but it isn't recommended.


List joined tables in the FROM clause, and place the conditions in the WHERE clause. FULL JOIN
SELECT * FULL JOIN returns all rows from the left table and all rows from the right table. It fills the non-
FROM toy, cat
matching rows with
WHERE toy.cat_id = cat.cat_id;
NULLs. FULL JOIN is also called FULL OUTER JOIN.
toy_id toy_name cat_id cat_id cat_name
JOIN CONDITIONS SELECT *
FROM toy 5 ball 1 1 Kitty
3 mouse 1 1 Kitty
The JOIN condition doesn't have to be an equality – it can be any condition you want. JOIN doesn't FULL JOIN cat NULL NULL NULL 2 Hugo
interpret the JOIN ON toy.cat_id = cat.cat_id; 1 ball 3 3 Sam
condition, it only checks if the rows satisfy the given condition. 4 mouse 4 4 Misty
2 spring NULL NULL NULL
whole left whole right table
To refer to a column in the JOIN query, you have to use the full column name: first the table name, table
then a dot (.) and the column name:
ON cat.cat_id = toy.cat_id
You can omit the table name and use just the column name if the name of the column is unique within
all columns in the joined tables. CROSS JOIN
CROSS JOIN returns all possible combinations of rows from the left and right tables.
NATURAL JOIN SELECT * toy_id toy_name cat_id cat_id cat_name
FROM toy 1 ball 3 1 Kitty
If the tables have columns with the same name, you can use 2 spring NULL 1 Kitty
NATURAL JOIN instead of JOIN. cat_id toy_id toy_name cat_name CROSS JOIN cat; 3 mouse 1 1 Kitty
1 5 ball Kitty 4 mouse 4 1 Kitty
SELECT * 1 3 mouse Kitty Other syntax:
5 ball 1 1 Kitty
FROM toy 3 1 ball Sam 1 ball 3 2 Hugo
4 4 mouse Misty SELECT *
NATURAL JOIN cat; 2 spring NULL 2 Hugo
FROM toy, cat; 3 mouse 1 2 Hugo
The common column appears only once in the result table. 4 mouse 4 2 Hugo
Note: NATURAL JOIN is rarely used in real life. 5 ball 1 2 Hugo
1 ball 3 3 Sam
··· ··· ··· ··· ···
COLUMN AND TABLE ALIASES MULTIPLE JOINS
Aliases give a temporary name to a table or a column in a
table. You can join more than two tables together. First, two tables are joined, then the third table is joined
CAT AS c OWNER AS o to the result of the previous joining.
cat_id cat_name mom_id owner_id id name
1 Kitty 5 1 1 John Smith
2 Hugo 1 2 2 Danielle Davis
3 Sam 2 2 TOY AS t
toy_id toy_name cat_id CAT AS c
4 Misty 1 NULL cat_id cat_name mom_id owner_id OWNER AS o
1 ball 3 id name
2 spring NULL 1 Kitty 5 1 John
3 mouse 1 2 Hugo 1 2 1 Smith
A column alias renames a column in the result. A table alias renames a table within the query. If 4 mouse 4 3 Sam 2 2 Danielle
4 Misty 1 NULL 2 Davis
you define a table alias, you must use it instead of the table name everywhere in the query. The AS 5 ball 1
keyword is optional in defining aliases.
SELECT
o.name AS owner_name, c.cat_name cat_name owner_name
FROM cat AS c Kitty John Smith JOIN & JOIN JOIN & LEFT JOIN LEFT JOIN & LEFT JOIN
Sam Danielle Davis
JOIN owner AS o Hugo Danielle Davis SELECT SELECT SELECT
ON c.owner_id = o.id; t.toy_name, t.toy_name, t.toy_name,
c.cat_name, c.cat_name, c.cat_name,
o.name AS owner_name o.name AS owner_name o.name AS owner_name
SELF JOIN FROM toy t FROM toy t FROM toy t
You can join a table to itself, for example, to show a parent-child relationship. JOIN cat c JOIN cat c LEFT JOIN cat c
ON t.cat_id = ON t.cat_id = ON t.cat_id = c.cat_id
CAT AS child CAT AS mom
cat_id cat_name owner_id mom_id cat_id cat_name owner_id mom_id c.cat_id c.cat_id LEFT JOIN owner o
1 Kitty 1 5 JOIN owner o LEFT JOIN owner o ON c.owner_id = o.id;
1 Kitty 1 5 2 Hugo 2 1 ON c.owner_id = o.id; ON c.owner_id = o.id; toy_name cat_name owner_name
toy_name cat_name owner_name toy_name cat_name owner_name ball Kitty John Smith
3 2 Hugo 2 1 Sam 2 2 ball Kitty John Smith ball Kitty John Smith mouse Kitty John Smith
3 Sam 2 2 4 Misty NULL 1 mouse Kitty John Smith mouse Kitty John Smith ball Sam Danielle Davis
4 Misty NULL 1 ball Sam Danielle Davis ball Sam Danielle Davis mouse Misty NULL
Each occurrence of the table must be given a different alias. Each column reference must be mouse Misty NULL spring NULL NULL
preceded with an
appropriate table alias.
SELECT
child.cat_name AS child_name, child_name mom_name
mom.cat_name AS mom_name Hugo Kitty
FROM cat AS child
Sam
Misty
Hugo
Kitty
JOIN WITH MULTIPLE CONDITIONS
JOIN cat AS mom You can use multiple JOIN conditions using the ON keyword once and the AND keywords as many times
ON child.mom_id = mom.cat_id; as you need.

NON-EQUI SELF JOIN CAT AS c


cat_id cat_name mom_id owner_id age
OWNER AS o
id name age
You can use a non-equality in the ON condition, for example, to show all different pairs of rows. 1 Kitty 5 1 17 1 John Smith 18
2 Hugo 1 2 10 2 Danielle Davis 10
TOY AS a TOY AS b 3 Sam 2 2 5
toy_id toy_name cat_id cat_id toy_id toy_name 4 Misty 1 NULL 11
3 mouse 1 1 3 mouse
5 ball 1 1 5 ball
1 ball 3 3 1 ball
4 mouse 4 4 4 mouse SELECT
2 spring NULL NULL 2 spring cat_name,
o.name AS owner_name,
c.age AS cat_age, o.age cat_name owner_name age age
SELECT cat_a_id toy_a cat_b_id toy_b
1 mouse 3 ball AS owner_age Kitty John Smith 17 18
a.toy_name AS toy_a, b.toy_name AS Sam Danielle Davis 5 10
1 ball 3 ball FROM cat c
toy_b 1 mouse 4 mouse JOIN owner o
FROM toy a JOIN toy b 1 ball 4 mouse ON c.owner_id =
ON a.cat_id < b.cat_id; 3 ball 4 mouse
o.id AND c.age <
o.age;
TEXT FUNCTIONS NUMERIC FUNCTIONS
To get the square root of a number:
SELECT SQRT(9); -- result: 3 NULLs
CONCATENATION BASIC OPERATIONS To retrieve all rows with a missing value in the price
Use the || operator to concatenate two strings: column:
Use / to do some basic math. To get the
SELECT 'Hi ' || 'there!'; WHERE price IS NULL
number of seconds in a week:
-- result: Hi there SELECT 60 * 60 * 24 * 7; -- result: 604800
Remember that you can concatenate only character To retrieve all rows with the weight column populated:
strings using CASTING WHERE weight IS NOT NULL
|. Use this trick for numbers: From time to time, you need to change the type of a
SELECT '' || 4 || 2; number. The CAST() function is there to help you out. Why shouldn't you use price = NULL weight !=
-- result: 42 It lets you change the type of value to almost anything NULL? Because databases don't know if those
Some databases implement non-standard solutions (integer numeric double precision varchar, and expressions are true or false – they are evaluated as
for concatenating strings like CONCAT() many more). NULL
Get the number as an integer (without rounding): Moreover, if you use a function or concatenation on a
CONCAT_WS(). Check the documentation for your
SELECT CAST(1234.567 AS integer) column that s NULL in some rows, then it will get
specific database.
-- result: 1234 propagated. Take a look:
LIKE OPERATOR – PATTERN MATCHING Change a column type to double precision
domain LENGTH(domain)
Use the character to replace any single character. SELECT CAST(column AS double precision)
Use the % character to replace any number of LearnSQL.com 12
characters (including 0 characters). USEFUL FUNCTIONS LearnPython.com 15
Fetch all names that start with any letter followed by Get the remainder of a division: ULL ULL
'atherine SELECT MOD(13, 2)
vertabelo.com 13
SELECT -- result: 1
ROM Round a number to its nearest integer:
WHERE name LIKE '_atherine' SELECT ROUND(1234.56789)
USEFUL FUNCTIONS
Fetch all names that end with a COALESCE(x, y, ...)
-- result: 1235
SELECT To replace NULL in a query with something meaningful:
Round a number to three decimal places: SELECT
ROM
SELECT ROUND(1234.56789, 3) domain,
WHERE name LIKE '%a
-- result: 1234.568 COALESCE(domain, 'domain missing')
USEFUL FUNCTIONS PostgreSQL requires the first argument to be of the FROM contacts;
Get the count of characters in a string: type
SELECT LENGTH('LearnSQL.com') numeric – cast the number when needed. domain coalesce
-- result: 12 LearnSQL.com LearnSQL.com
To round the number up
Convert all letters to lowercase: SELECT CEIL(13.1) -- result: 14 NULL domain missing
SELECT LOWER('LEARNSQL.COM ) SELECT CEIL(-13.9); -- result: -13 The COALESCE() function takes any number of
-- result: learnsql.com The CEIL(x) function returns the smallest integer not arguments and returns the value of the first
Convert all letters to uppercase: less than argument that isn't NULL
SELECT UPPER('LearnSQL.com ) x. In SQL Server, the function is called CEILING()
-- result: LEARNSQL.COM To round the number down: NULLIF(x, y)
Convert all letters to lowercase and all first letters to SELECT FLOOR(13.8); -- result: 13 To save yourself from division by 0 errors:
uppercase (not implemented in MySQL and SQL SELECT FLOOR(-13.2); -- result: -14 SELECT
Server): The FLOOR(x) function returns the greatest integer not last_month,
SELECT INITCAP('edgar frank ted cODD ) greater this_month,
-- result: Edgar Frank Ted Codd than x this_month * 100.0
Get just a part of a string: / NULLIF(last_month, 0)
To round towards 0 irrespective of the sign of a
SELECT SUBSTRING('LearnSQL.com', 9) AS better_by_percent
number: SELECT TRUNC(13.5); -- result: FROM video_views;
-- result: .com
13 SELECT TRUNC(-13.5); -- result: -13
SELECT SUBSTRING('LearnSQL.com', 0, 6)
TRUNC(x) works the same way as CAST(x AS last_month this_month better_by_percent
-- result: Learn integer). In 723786 1085679 150.0
Replace part of a string: MySQL, the function is called TRUNCATE()
SELECT REPLACE('LearnSQL.com', 'SQL', 0 178123 ULL
To get the absolute value of a number:
'Python') The NULLIF(x, y) function will return NULL if is the
SELECT ABS(-12); -- result: 12
-- result: LearnPython.com
same as documentation if they do. For example, if you want to
y, else it will return the value. CASE WHEN specify the rounding precision in PostgreSQL, the
The basic version of CASE WHEN checks if the values value must be of the numeric type.
are equal (e.g., if fee is equal to 50, then normal'
is returned). If there isn't a matching value in the
CASE WHEN, then the ELSE value will be returned
(e.g., if fee is equal to 49, then not available'
will show up.
SELECT
CASE fee
WHEN 50 THEN
'normal' WHEN 10
THEN 'reduced WHEN 0
THEN 'free
ELSE 'not available'
END AS tariff
FROM ticket_types;
The most popular type is the searched CASE WHEN – it
lets you pass conditions (as you'd write them in the
WHERE clause), evaluates them in order, then returns
the value for the first condition met.
SELEC
T
CASE
WHEN score >= 90 THEN
'A' WHEN score > 60 THEN
'B' ELSE 'F
ND AS grade
FROM test_results;
Here, all students who scored at least 90 will get an A,
those with
the score above 60 (and below 90) will get a B, and the
rest will receive an F.

TROUBLESHOOTING
Integer division
When you don't see the decimal places you expect, it
means that you are dividing between two integers.
Cast one to decimal CAST(123 AS decimal) / 2
Division by 0
To avoid this error, make sure that the denominator is
not equal to 0. You can use the NULLIF() function
to replace 0 with a NULL, which will result in a NULL
for the whole expression: count /
NULLIF(count_all, 0)
Inexact calculations
If you do calculations using real (floating point)
numbers, you'll end up with some inaccuracies. This is
because this type is meant for scientific calculations
such as calculating the velocity.
Whenever you need accuracy (such as dealing with
monetary values), use the decimal / numeric type
(or money if available).
Errors when rounding with a specified precision
Most databases won't complain, but do check the
AGGREGATION AND GROUPING DATE AND TIME INTERVALs TIME ZONES
COUNT(expr) – the count of values for the rows There are 3 main time-related types: date time, and Note: In SQL Server, intervals aren't implemented – use In the SQL Standard, the date type can't have an
within the group timestamp. Time is expressed using a 24-hour clock, the associated time zone, but the time and timestamp
SUM(expr) – the sum of values within the group and it can be as vague as just hour and minutes (e.g., DATEADD() and DATEDIFF() functions. types can. In the real world, time zones have little
AVG(expr) – the average value for the rows within 15:30 – 3:30 p.m.) or as precise as microseconds meaning without the date, as the offset can vary
the group and time zone (as shown below): through the year because of daylight saving time.
To get the simplest interval, subtract one time
MIN(expr) – the minimum value within the group value from another: So, it's best to work with the timestamp values.
2021-12-31 14:39:53.662522-05
MAX(expr) – the maximum value within the group date time SELECT CAST('2021-12-31 23:59:59' AS When working with the type timestamp with time
To get the number of rows in the table: timestamp) CAST( 2021-06-01 12:00:00' AS zone (abbr. timestamptz), you can type in the value
timestamp
SELECT COUNT( ) timestamp) in your local time zone, and it'll get converted to the
YYYY-mm-dd HH:MM:SS.ssssss±TZ -- result: 213 days 11:59:59 UTC time zone as it is inserted into the table. Later
FROM city;
when you select from the table it gets converted
4:39:53.662522-05 is almost 2:40 p.m. CDT (e.g.,
To get the number of non-NULL values in a column: back to your local time zone. This is immune to time
in Chicago; in UTC it'd be 7:40 p.m.). The letters in To define an interval: INTERVAL '1' DAY
SELECT COUNT(rating) zone changes.
the above example represent: This syntax consists of three elements: the INTERVAL
ROM city;
keyword, a

To get the count of unique values in a In the date In the time part: quoted value, and a time part keyword (in singular AT TIME ZONE
column: SELECT COUNT(DISTINCT part: YYYY – form.) You can use the following time parts: YEAR To operate between different time zones, use the AT
HH – the zero-padded hour in a
country_id) FROM city; the 4-digit 24- hour clock. MONTH WEEK DAY HOUR MINUTE, and SECOND. In TIME ZONE keyword.
year. MySQL, omit the quotes. You can join many different
MM – the minutes. If you use this format: {timestamp without time
GROUP BY mm – the zero- SS – the seconds. Omissible
INTERVALs using the + operator:
INTERVAL '1' YEAR + INTERVAL '3' MONTH zone} AT TIME ZONE {time zone}, then the
CITY padded month ssssss – the smaller parts database will read the time stamp in the specified
(01—January
country_id of a second – they can be time zone and convert it to the time zone local to the
through 12 In some databases, there's an easier way to get the
Paris 1 expressed using 1 to 6 display. It returns the time in the format timestamp
December). above value. And it accepts plural forms! INTERVAL
digits. Omissible with time zone
Marseille 1 dd – the zero- '1 year 3 months
±TZ – the timezone. It must If you use this format: {timestamp with time zone}
Lyon 1 padded day. There are two more syntaxes in the Standard SQL:
AT TIME ZONE {time zone}, then the database will
start with either or , and
Berlin 2 use two digits relative to Syntax What it does convert the time in one time zone to the target time
zone specified by AT TIME ZONE. It returns the time in
Hamburg 2 UTC. Omissible INTERVAL 'x-y' YEAR TO INTERVAL 'x year y
the format timestamp without time zone, in the
Munich 2 MONTH month
What time is it? target time zone.
Warsaw 4 project after the JOIN. To get the correct count (0 for INTERVAL
To 'x-y'
answer that DAY TO
question INTERVAL
in SQL, 'x day y
you can use: You might skip casting in simple conditions – the
the clients you've never worked for), count the values SECOND second database will know what you mean.
Cracow 4 CURRENT_TIME – to find what time it is.
in a column of the other table, e.g., SELECT airline, flight_number, departure_time
CURRENT_DATE – to get today's date. (GETDATE()
COUNT(project_name). Check out this exercise to see FROM airport_schedule
an example. in SQL Server.)
WHERE departure_time < '12:00';
CURRENT_TIMESTAMP – to get the timestamp with
The example above – the count of cities in each the two above.
country:
SELECT name, COUNT(country_id)
Creating values
FROM city
To create a date time, or timestamp, simply write
GROUP BY name;
the value as a string and cast it to the proper type.
The average rating for the city: SELECT CAST( 2021-12-31' AS
SELECT city_id, AVG(rating) date) SELECT CAST( 15:31' AS
ROM ratings time)
GROUP BY city_id; SELECT CAST( 2021-12-31 23:59:29+02' AS
timestamp)
Common mistake: COUNT(*) and LEFT JOIN
SELECT CAST( 15:31.124769' AS time)
When you join the tables like this: client LEFT
Be careful with the last example – it will be
JOIN project, and you want to get the number of
interpreted as 15 minutes 31 seconds and 124769
projects for every client you know, COUNT(*) will
microseconds! It is always a good idea to write 00
return 1 for each client even if you've never worked
explicitly for hours: '00:15:31.124769
for them. This is because, they're still present in the
list but with the NULL in the fields related to the
CITY
country_id count
1 3
2 3
4 2 You can define the time zone with popular shortcuts
like UTC MST, or GMT, or by continent/city such as:
America/New_York Europe/London, and Asia/Tokyo
In MySQL, write year_month instead of YEAR TO
MONTH and Examples
day_second instead of DAY TO SECOND We set the local time zone to 'America/New_York'
SELECT TIMESTAMP '2021-07-16 21:00:00' AT
To get the last day of a month, add one month and TIME ZONE 'America/Los_Angeles';
subtract one day: -- result: 2021-07-17 00:00:00-04
SELECT CAST('2021-02-01' AS
Here, the database takes a timestamp without a time
date INTERVAL '1'
zone and it's told it's in Los Angeles time, which is
MONTH
then converted to the local time – New York for
INTERVAL '1' DAY
displaying. This answers the question "At what time
should I turn on the TV if the show starts at 9 PM in
To get all events for next three months from today: Los Angeles?"
SELECT event_date, event_name
FROM calendar
SELECT TIMESTAMP WITH TIME ZONE '2021-06-20
WHERE event_date BETWEEN CURRENT_DATE AND
19:30:00' AT TIME ZONE 'Australia/Sydney';
CURRENT_DATE + INTERVAL '3' MONTH
-- result: 2021-06-21 09:30:00
Here, the database gets a timestamp specified in the
To get part of the date:
local time zone and converts it to the time in Sydney
SELECT EXTRACT(YEAR FROM birthday) (note that it didn't return a time zone.) This answers the
FROM artists; question "What time is it in Sydney if it's 7:30 PM
One of possible returned values: 1946. In SQL Server, use here?"
the
DATEPART(part, date) function.

You might also like