command | description |
---|---|
\c | connect |
\l | list databases |
\d | list visible tables |
\d <table_name> | list table details |
\i FILE | execute commands from file |
\q | quit |
\x | toggle expanded display |
CREATE DATABASE test;
DROP DATABASE test;
CREATE TABLE person (
id int,
first_name VARCHAR(50),
last_name VARCHAR(50),
gender VARCHAR(7),
date_of_birth DATE
);
DROP TABLE person;
CREATE TABLE person (
id BIGSERIAL NOT NULL PRIMARY KEY,
first_name VARCHAR(50) NOT NULL,
last_name VARCHAR(50) NOT NULL,
gender VARCHAR(7) NOT NULL,
date_of_birth DATE NOT NULL,
email VARCHAR(150)
);
INSERT INTO person (
first_name,
last_name,
gender,
date_of_birth
)
VALUES (
'Anne', 'Smith', 'FEMALE', DATE '1988-01-09'
);
INSERT INTO person (
first_name,
last_name,
gender,
date_of_birth,
email
)
VALUES (
'Jake', 'Jones', 'MALE', DATE '1990-01-10', '[email protected]'
);
Before proceeding, inspect and run the person.sql script.
\i person.sql
SELECT * FROM person;
SELECT first_name, last_name FROM person;
Type | Value | Example |
---|---|---|
Ascending | ASC | 1, 2, 3, 4, 5 |
Descending | DESC | 5, 4, 3, 2, 1 |
- ORDER BY defaults to ASC order if no other value is specified.
ORDER BY single column
SELECT * FROM person ORDER BY id DESC;
ORDER BY multiple columns
SELECT * FROM person ORDER BY first_name, email DESC;
SELECT DISTINCT country_of_birth FROM person ORDER BY country_of_birth;
Filter data based on conditions
SELECT * FROM person WHERE gender = 'Male';
SELECT * FROM person WHERE gender='Female' AND country_of_birth = 'Brazil';
SELECT * FROM person WHERE first_name = 'Robert' OR first_name = 'Cash';
Operator | Description |
---|---|
= | equal to |
<> | not equal to |
> | greater than |
>= | greater than or equal to |
< | less than |
< | less than or equal to |
SELECT 1 = 1;
SELECT * from person WHERE date_of_birth >= '2018-10-15'::date AND date_of_birth <= '2018-11-01'::date;
Limit number of returned results to 10 records.
SELECT * FROM person LIMIT 10;
Same as LIMIT but SQL standard.
SELECT * FROM person FETCH FIRST 5 ROW ONLY;
SELECT * FROM person OFFSET 5 LIMIT 10;
Selecting all people from China, Brazil or France.
SELECT * FROM person WHERE country_of_birth = 'China' OR country_of_birth = 'Brazil' OR country_of_birth = 'France';
Using the IN keyword, the statement can be re-written as
SELECT * FROM person WHERE country_of_birth IN ('China', 'France', 'Brazil');
Select data from a range.
SELECT * FROM person WHERE date_of_birth BETWEEN DATE '2018-10-01' AND '2018-10-15';
Used to match text values against a pattern using wild cards.
SELECT * FROM person WHERE email LIKE '%.com';
SELECT * FROM person WHERE email lIKE '%@mozilla.%';
Use _ to match single chars
SELECT * FROM person WHERE email lIKE '________@%'
Same as like but case insensitive.
SELECT * FROM person WHERE country_of_birth ILIKE 'p%';
SELECT COUNT(id), country_of_birth FROM person GROUP BY country_of_birth ORDER BY count DESC;
Add an extra filter after performing aggregation.
SELECT COUNT(id), country_of_birth FROM person GROUP BY country_of_birth HAVING COUNT(id) > 10 ORDER BY count ASC;
Before proceeding, inspect and run the car.sql script.
\i car.sql
SELECT MAX(price) FROM car;
SELECT MIN(price) FROM car;
Get lowest price for all make and models.
SELECT make, model, MIN(price) FROM car GROUP BY make, model;
SELECT AVG(price) FROM car;
SELECT ROUND(AVG(price)) FROM car;
SELECT SUM(price) FROM car;
Symbol | Description |
---|---|
+ | Addition |
- | Subtraction |
* | Multiplication |
/ | Division |
^ | Exponentiation |
! | Factorial |
% | Modulo |
SELECT 1 + 1; # 1
SELECT 4 - 2; # 2
SELECT 7 * 7; # 49
SELECT 100 / 10; # 10
SELECT 3 ^ 3; # 27
SELECT 5!; # 5 * 4 * 3 * 2 * 1 = 120
SELECT 10 % 3; # 1
Get the value of an item with a discount.
SELECT id, make, model, price, price * .90 FROM car LIMIT 10;
SELECT id, make, model, price, price * .90 AS discounted_price FROM car LIMIT 10;
If value not present, attempt to use the next value in the array.
SELECT COALESCE(null, 1); # 1
SELECT COALESCE(email, 'EMAIL-NOT-PROVIDED') FROM person;
Returns the first argument if the second argument is not equal to the first.
SELECT NULLIF(10, 1); # 10
SELECT NULLIF(10, 10); # NULL
Useful for preventing division by zero.
SELECT 10 / 0; # ERROR: division by zero
SELECT 10 / NULL; # NULL
SELECT COALESCE(10 / NULLIF(0, 0), 0); # 0
SELECT NOW(); # TIMESTAMP
SELECT NOW()::DATE; # CAST TO DATE
SELECT NOW()::TIME; # CAST TO TIME
Date subtraction.
SELECT NOW() - INTERVAL '10 YEAR'; # CAN ALSO USE YEARS
SELECT NOW() - INTERVAL '10 MONTH'; # CAN ALSO USE MONTHS
SELECT NOW() - INTERVAL '10 DAY'; # CAN ALSO USE DAYS
Date addition.
SELECT NOW() + INTERVAL '10 YEAR'; # CAN ALSO USE YEARS
SELECT NOW() + INTERVAL '10 MONTH'; # CAN ALSO USE MONTHS
SELECT NOW() + INTERVAL '10 DAY'; # CAN ALSO USE DAYS
Casting entire statement.
SELECT DATE(NOW() + INTERVAL '10 MONTHS');
Extract values from a given TIMESTAMP.
SELECT EXTRACT(YEAR FROM NOW()); # YEAR 2019
SELECT EXTRACT(MONTH FROM NOW()); # MONTH 10
SELECT EXTRACT(DAY FROM NOW()); # DAY 10
SELECT EXTRACT(DOW FROM NOW()); # DAY OF WEEK 4 (THURSDAY)
SELECT EXTRACT(CENTURY FROM NOW()); # CENTURY 21
SELECT first_name, last_name, gender, country_of_birth, date_of_birth, AGE(NOW(), date_of_birth) AS age FROM person;
Uniquely identifies a record in a table.
The person table has a constraint associated with it to prevent duplicate ids. If an INSERT statement attempts to add a user with the same ID on this table, the following error will be issued:
ERROR: duplicate key value violates unique constraint "person_pkey"
Dropping a constraint.
ALTER TABLE person DROP CONSTRAINT person_pkey;
Adding PRIMARY KEY constraint
ALTER TABLE person ADD PRIMARY KEY (id);
DELETE FROM person WHERE id = 1;
Create a unique constraint allowing Postgres to name it.
ALTER TABLE person ADD UNIQUE(email);
Create a unique constraint providing Postgres with a custom name for the same.
ALTER TABLE person ADD CONSTRAINT unique_email_address UNIQUE(email);
ALTER TABLE PERSON ADD CONSTRAINT gender_constraint CHECK (gender = 'Female' OR gender = 'Male' OR gender='Other');
UPDATE person SET first_name = 'Marg', mail = '[email protected]' WHERE id = 1;
INSERT INTO person (id, first_name, last_name, gender, date_of_birth, email, country_of_birth)
VALUES (1, 'Martguerita', 'Riddoch', 'Female', '2019-09-05', '[email protected]', 'Sweden')
ON CONFLICT (id) DO NOTHING;
INSERT INTO person (id, first_name, last_name, gender, date_of_birth, email, country_of_birth)
VALUES (1, 'Martguerita', 'Riddoch', 'Female', '2019-09-05', '[email protected]', 'Sweden')
ON CONFLICT (id) DO UPDATE SET email = EXCLUDED.email;
A foreign key is a column that references a primary key in another table.
A car has a vin number. A vin number can only be associated with one car.
Before proceeding, inspect and run the vin_number.sql script.
\i vin_number.sql
An inner join returns the items that are common in both tables.
SELECT * FROM car JOIN vin_number ON car.vin_id = vin_number.id;
A left join includes all of the rows from the left table with the corresponding rows on the right table.
SELECT * FROM car LEFT JOIN vin_number ON car.vin_id = vin_number.id WHERE car.id < 5;
A car can have multiple service records. A service record can only be associated with one car.
Before proceeding, inspect and run the service_record.sql script.
\i service_record.sql
SELECT * FROM car JOIN service_record ON car.id = service_record.id;
A person can own many vehicles. A car can have multiple owners.
Before proceeding, inspect and run the person_car_mapping.sql script.
\i person_car_mapping.sql
SELECT p.id AS PERSON_ID, p.first_name, p.last_name, c.id AS CAR_ID, c.make, c.model
FROM person AS p, car AS c, person_car_mapping as pc
WHERE pc.car_id = c.id AND pc.person_id = p.id;