Skip to content

SQL Language

This chapter is dedicated to common SQL implementation, including complex statements.

WITH

The WITH clause allows to create temporary named result sets that exist only for the duration of the query. It is like creating a temporary view or defining a sub-query that we can reference multiple times. It is named CTE for Common Table Expressions.

WITH cte_name AS (
    SELECT column1, column2
    FROM table_name
    WHERE condition
)
SELECT * FROM cte_name;

Can be used for recursive queries: Like get the list of employees

WITH RECURSIVE employee_hierarchy AS (
    -- Base case: get top-level employees
    SELECT employee_id, name, manager_id, 1 as level
    FROM employees
    WHERE manager_id IS NULL

    UNION ALL

    -- Recursive case: get subordinates
    SELECT e.employee_id, e.name, e.manager_id, h.level + 1
    FROM employees e
    JOIN emp_hierarchy h ON e.manager_id = h.employee_id
)
SELECT * FROM emp_hierarchy;

Joins

A JOIN combines rows from two or more tables based on a related column between them. There are several types of JOINs:

INNER JOIN

Te goal is to build a projection of all elements in table A also present in table B. Get all columns of both tables:

SELECT * FROM table_a INNER JOIN table_b on table_a.column = table_b.column_b
-- Returns only the matching rows from both tables
SELECT employees.name, departments.dept_name
FROM employees
INNER JOIN departments 
    ON employees.dept_id = departments.id;

It is used to find matches between tables, or to get complete records only.

  • Get the top 10 customer name who do the most renting
select first_name, last_name, count(*) from payment 
inner join customer 
on payment.customer_id = customer.customer_id 
group by first_name, last_name 
order by count(*) desc limit 10;
-- get email address of customer leaving in california
select district, email from customer
join address
on address.address_id = customer.address_id
where address.district = 'California'

LEFT (OUTER) JOIN

OUTER JOIN is used to deal with column only in one table. Returns all rows from left table and matching rows from right table.

SELECT employees.name, departments.dept_name
FROM employees
LEFT JOIN departments 
    ON employees.dept_id = departments.id;
-- Will show all employees, even those without departments

It is used for checking for missing records, or to report with all records from a main table.

Another example:

select title, inventory_id, store_id from film 
left join inventory 
on film.film_id = inventory.film_id

RIGHT (OUTER) JOIN:

Returns all rows from right table and matching rows from left table.

SELECT employees.name, departments.dept_name
FROM employees
RIGHT JOIN departments 
    ON employees.dept_id = departments.id;
-- Will show all departments, even those without employees

FULL OUTER JOIN

Returns all rows from both tables.

-- full outer join - customer never buy anything
select * from customer 
full outer join payment 
on payment.customer_id = customer.customer_id
where customer.customer_id IS null;
-- set of records that are in the left table, present or not in the right

Another example:

-- film in catalog not in the inventory
select title, inventory_id, store_id from film 
left join inventory 
on film.film_id = inventory.film_id
where inventory_ID IS null

Combining Joins

-- Example with three tables
SELECT 
    e.name AS employee_name,
    d.dept_name,
    p.project_name
FROM employees e
INNER JOIN departments d 
    ON e.dept_id = d.id
LEFT JOIN projects p 
    ON e.project_id = p.id
WHERE d.location = 'New York';

Some practices

  • Always use table aliases for better readability
  • Specify the JOIN type explicitly (don't rely on implicit joins)
  • Be careful with OUTER JOINs as they can impact performance
  • Use appropriate indexes on join columns
  • Consider the order of joins when working with multiple tables

  • What are the film with a given actor?

    select  title,first_name, last_name from film_actor as fa
    inner join actor
    on actor.actor_id = fa.actor_id
    inner join film
    on fa.film_id = film.film_id
    where last_name = 'Wahlberg' and first_name = 'Nick'
    
  • Film returned on a specific date: uses subquery, and joins

    select film_id,title from film
    where film_id in
    (select inventory.inventory_id from rental 
    inner join inventory
    on inventory.inventory_id = rental.inventory_id
    where rental.return_date between '2005-05-29' and ' 2005-05-30')
    ORDER BY title