SQL-шпаргалка

Это шпаргалка для студентов моих курсов по SQL и вообще всех, кто когда-то знал SQL, но подзабыл.

Мы будем использовать таблицу cities с городами России, население которых превышает 500 тыс. человек. Примеры интерактивные, так что можно заодно и потренироваться.

Основы

Базовые элементы, из которых строятся запросы.

select ... from ...

Выбирает строки из указанной таблицы. В каждой строке оставляет только перечисленные столбцы.

select city, population, timezone
from cities;

where

Оставляет в результате только те строки, которые подходят под условие.

select population, timezone
from cities
where city = 'Самара';

Условия бывают разные:

  • строгое равенство: city = 'Самара'
  • неравенство: population > 10000
  • вхождение в диапазон: foundation_year between 1900 and 2000
  • вхождение в перечисленный список: region_type in ('край', 'обл')
  • совпадение с шаблоном: postal_code like '105%'
  • проверка на пустое значение: area is null

Условия можно комбинировать через or (выбрать строки, которые подходят под любое из условий):

select city, population
from cities
where city = 'Самара' or city = 'Новосибирск';

Или через and (выбрать строки, которые подходят одновременно под все условия):

select city, population
from cities
where federal_district = 'Сибирский' and region_type = 'край'

distinct

Выбирает только уникальные значения (то есть без повторов) перечисленных в select столбцов:

select distinct region_type
from cities;

order by

Сортирует результат по указанным столбцам.

select city, population
from cities
order by population;

По умолчанию сортирует от меньшего к большему, но если добавить desc — то наоборот:

select city, population
from cities
order by population desc;

limit

Оставляет только первые N строк результата. Обычно используется в связке с order by

select city, population
from cities
order by population
limit 5;

Группировка

Объединяем данные в группы и считаем сводные показатели.

group by

Объединяет строки с одинаковым значением указанных столбцов. Используется в связке с одной из агрегатных функций:

count(*) — количество строк с одинаковым значением столбца из group by

-- количество городов в каждом федеральном округе
select federal_district, count(*)
from cities
group by federal_district;

sum(column) — сумма значений столбца column по строкам с одинаковым значением столбца из group by

-- общее население каждого федерального округа
select federal_district, sum(population)
from cities
group by federal_district;

avg(column) — среднее значение столбца column по строкам с одинаковым значением столбца из group by

-- среднее население города в каждом федеральном округе
select federal_district, avg(population)
from cities
group by federal_district;

max(column) — максимальное значение столбца column среди строк с одинаковым значением столбца из group by

-- самое большое население города в каждом федеральном округе
select federal_district, max(population)
from cities
group by federal_district;

min(column) — минимальное значение столбца column среди строк с одинаковым значением столбца из group by

-- самое маленькое население города в каждом федеральном округе
select federal_district, min(population)
from cities
group by federal_district;

having

Отсеивает строки из результата уже после того, как отработал group by. Этим отличается от where, который отсеивает до того, как отработал group by.

-- федеральные округа, в которых больше 5 городов
select federal_district, count(*)
from cities
group by federal_district
having count(*) > 5;

Соединение таблиц

Соединение нескольких таблиц в результате запроса.

Допустим, есть две таблицы — вакансии (vacancy) и работодатели (employer):

Таблицы

В таблице вакансий есть идентификатор работодателя — employer_id. А вот названия работодателя нет, оно в таблице employer.

Внутренний JOIN (он же INNER JOIN)

Мы хотим выбрать записи из vacancy, но добавить к ним название работодателя (employer.name). В этом поможет операция соединения таблиц — join:

Внутренний JOIN
select
  vacancy.id,
  vacancy.name,
  vacancy.employer_id,
  employer.name as employer_name
from vacancy
  join employer on vacancy.employer_id = employer.id;

Для каждой строчки vacancy движок базы данных лезет в таблицу employer, находит там значение id = vacancy.employer_id, извлекает name и добавляет в результат.

Если подходящее значение в employer не найдено (как для «инженера» в vacancy) — строчка не попадает в результат.

Внешний левый JOIN (LEFT JOIN)

Внешнее левое соединение очень похоже на обычное:

Внешний левый JOIN
select
  vacancy.id,
  vacancy.name,
  vacancy.employer_id,
  employer.name as employer_name
from vacancy
  left join employer on vacancy.employer_id = employer.id;

Разница только в том, что даже когда в employer не найдена строчка с id = vacancy.employer_id («инженер» в нашем примере) — строчка из vacancy все равно попадает в результат. Название работодателя при этом будет null.

Внутренний JOIN как бы говорит:

Дай записи из двух таблиц, у которых есть совпадение по указанному критерию.

Внешний левый JOIN же говорит:

Дай записи из двух таблиц, у которых есть совпадение по указанному критерию. И добавь к ним все записи из левой таблицы, для которых нет совпадения в правой.

Внешние соединения бывают не только левые, но еще правые (right join) и полные (full join). Детали в статье о JOIN.

Итого

Мы рассмотрели самые-самые основы SQL для выборки данных («селекты»):

  • разделы запроса: столбцы, таблицы, фильтрация, сортировка;
  • группировка данных и функции агрегации;
  • соединение таблиц.

Конечно, у SQL намного больше возможностей, но это уже совсем другая история.

──

P.S. Хотите освоить современный SQL? Обратите внимание на Оконные функции

Подписывайтесь на канал, чтобы не пропустить новые заметки 🚀