SQL Query Cheatsheet for Postgres
Tags: Postgres, Data Science, Software Development, Programming, Sql

Where Clauses

The big section.

Operators

We can use all the equality operators you’d expect in a where clause: = , <> , != , <, <= , >= , > .

Find all records where the name is exactly “Liam”.

select * from users where first_name = 'Liam'

Find all records where the name is not “Liam”.

select * from users where first_name != 'Liam'

Find all records where id is greater or equal to 5.

select * from users where id >= 5

And, Or, Not

Chain multiple where clauses together with and , or and not . But notice we only write the where word once.

Select all records where the name is exactly “Liam” or “Olivia”.

select * from users where first_name = 'Liam' or first_name = 'Olivia';

Select all records where the name is exactly “Liam” AND the id is 5. This returns none because Liam’s id is not 5.

select * from users where first_name = 'Liam' and id = 5;

Select all records where the name is “Liam” AND the id is NOT 5. This returns Liam now.

select * from users where first_name = 'Liam' and not id = 5;

In

Rather than chaining clauses with or, or, or… you can find records where a value exists in a given array.

select * from users where first_name in ('Liam', 'Olivia');

Null

We can also load records where a value is (or is not) null.

select * from sales where user_id is null;

select * from sales where user_id is not null;

Fuzzy matching

Sometimes we want to find values that roughly match a query. For this, we can search on partial strings or ignore capitalization.

Load any records with the characters “ia” in the name.

select * from users where first_name like '%ia%';

Load records with the characters “IA” in the name. This returns nothing because no names have capitalized “IA” in them.

select * from users where first_name like '%IA%';

So let’s do a search ignoring cases.

select * from users where first_name ilike ‘%IA%’;

Where in subqueries

We already know we can do this.

select * from users where id > 5;

But we can also select from this query! Note you need to provide an alias for a subquery to work or an error will be thrown.

select

first_name

from (

select * from users where id > 5

) subquery;

With

Although we can query from another query, I prefer this approach. It feels much cleaner to define the subqueries in advance.

with cte as (

select * from users where id > 5

)

select

first_name

from cte

Date filtering

We can filter by dates.

Useful if you want to find all the transactions that occurred after a specific date.

select * from sales where created_at > '2016–01–01';

We can also find transactions between 2 dates.

select

*

from sales

where created_at between '2016–01–01' and '2017–01–01';

JSON(B)s

Postgres has some pretty awesome functionality for working with JSON.

Find records that have the key, in_stock in the data column.

select * from products where data -> 'in_stock' is not null;

Find records where the value of in_stock is greater than 5. Notice we need to cast JSONB to an integer to do the comparison.



select * from products where (data -> 'in_stock')::int > 5;

Select out data from the JSONB, as JSONB.

select name, data -> 'in_stock' as stock from products;

Select it out as text. The data type can have an impact in a more complex query where this value has other functions run on it.

select name, data ->> 'in_stock' as stock from products;

Lag

Get a record in the table and attach the record immediately before it.

Useful when looking at events over time where previous events affect future events. You might use data queried like this to train an ML model to predict a future state given the current state.

We’ll use it to find the user added immediately before every other user.

select

first_name as joined_user,

lag(first_name) over (order by created_at) as prev_joined_user

from users;

We get null as the previous user for Liam because he was the first to be added to the database.

Lead

The opposite of above. Load the user that joined immediately after each other user.