Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Technical Portfolio
GitHub & GitVerse Pages

Предметный указатель

SQL Lab in JupyterLab

Data & BI Analyst

Abstract

Решил попробовать создать персональный CheatSeet. Пока не нравится. Либо пойму как переделать, либо удалю.

Тем более что существут интерактивные справочники:

SQL Style Guide

Ключевые правила хорошего тона (своего рода “SQL-PEP8”):

1. Ключевые слова – ЗАГЛАВНЫМИ БУКВАМИ:

  • SELECT, FROM, WHERE, AND, OR, ORDER BY, TIMESTAMP.

2. Имена таблиц и колонок – маленькими буквами (snake_case):

  • users, date_joined, first_name.

3. Отступы (Indentations):

  • Стандартный отступ – 4 пробела (как в Python) или 2 пробела. \

Главное – соблюдать единообразие во всём файле.

4. Перенос условий в WHERE:

  • Каждое условие с AND или OR пишется с новой строки.

  • Служебное слово AND / OR обычно выравнивают:

-- Стиль с отступом в 2 пробела:
WHERE email ILIKE '%@bk.ru'
  AND EXTRACT(year FROM date_joined) = 2022

-- Либо стиль с отступом в 4 пробела:
WHERE email ILIKE '%@bk.ru'
    AND EXTRACT(year FROM date_joined) = 2022

5. Запятые в SELECT:

  • Каждое поле – строго на отдельной строке. Запятая ставится в конце строки (trailing commas):

SELECT
    id,
    username,
    email,
    date_joined
FROM users

6. По поводу функций в мире SQL есть два лагеря:

Школа 1 (Классическая / ANSI SQL / GitLab / большинство учебников): \

  • Правило: Всё, что встроено в язык и систему (ключевые слова + типы данных + встроенные функции), пишется ЗАГЛАВНЫМИ БУКВАМИ, а всё, что создал пользователь (таблицы, колонки, алиасы), – строчными.

  • Пример:

SELECT 
    user_id, 
    ROUND(score, 2), 
    COALESCE(email, 'нет'), 
    DATE_TRUNC('month', date_joined)
FROM users;
  • Плюс: Глаз мгновенно видит логику: белые/синие заглавные буквы – это операторы и функции, а маленькие строчные – это данные из таблицы.

Школа 2 (PostgreSQL Native / SQLFluff default / DBeaver):

  • Правило: Ключевые слова каркаса (SELECT, FROM, WHERE, JOIN) – ЗАГЛАВНЫМИ, а вызовы функций (count(), round(), to_char()) – строчными (как функции в Python: print(), len()).

  • Почему именно в PostgreSQL и DBeaver так любят строчные? В системных таблицах каталога PostgreSQL (pg_proc) все имена встроенных функций физически записаны маленькими буквами: date_trunc, to_char, lower. DBeaver берёт подсказки напрямую из системного каталога Postgres, поэтому и подставляет их в строчном виде.


Оба варианта признаются профессиональными. Главное – быть последовательным внутри своего проекта:

  • Если пишешь ROUND(), COALESCE(), TO_CHAR() заглавными – пиши их все заглавными.

  • Если решил писать строчными round(), coalesce(), to_char() – пусть они все будут строчными.


SQLFluff, dbt Style Guide и GitLab SQL Style Guide

Все три сущности – это общепринятые в индустрии стандарты и инструменты, решающие одну задачу: сделать SQL-код в командах аккуратным, предсказуемым и легко читаемым без бесконечных споров на код-ревью.

SQLFluff (Автоматический контролёр качества кода)
SQLFluff – открытый диалектно-независимый линтер и автоформатер для SQL.

  • Как работает: Анализирует код на соответствие правилам выбранного стайлгайда (регистры, отступы, порядок предложений, пробелы вокруг операторов). Если в коде нарушен стандарт, линтер выведет список ошибок с точными строками и номерами правил.

  • Команда sqlfluff fix: Автоматически форматирует файл и исправляет большинство проблем с отступами, регистрами ключевых слов и переносами за доли секунды.

  • Связь с практикой: SQLFluff выполняет ту же роль для SQL, что flake8, black или ruff для Python.

dbt Style Guide (Стандарт современной аналитики и DWH)
Руководство по стилю от создателей dbt Labs – де-факто мировой ориентир для аналитиков данных и дата-инженеров, работающих с облачными хранилищами (Snowflake, BigQuery, ClickHouse, Redshift).

  • Строчные ключевые слова: В отличие от классической школы ANSI SQL, dbt рекомендует писать все ключевые слова (select, from, where, group by) строчными буквами (lowercase).

  • Приоритет CTE: Запрет на глубоко вложенные подзапросы в блоках FROM и JOIN. Любая промежуточная логика оформляется в виде именованных выражений WITH в самом начале запроса.

  • Явные псевдонимы: Обязательное использование ключевого слова as при назначении алиасов колонкам (count(*) as total_records).

  • Запятые строго в конце строки: Стандарт dbt прямо предписывает использовать замыкающие запятые (trailing commas), как и в классическом SQL.

GitLab SQL Style Guide (Корпоративный стандарт ИТ-гиганта)
GitLab SQL Style Guide – публичный внутренний стандарт команды платформы данных компании GitLab (в первую очередь ориентированный на PostgreSQL и Snowflake).

  • Явные соединения: Полный запрет на устаревшие неявные соединения через запятую из стандарта SQL-89 (FROM a, b WHERE a.id = b.id). Допускаются только явные INNER JOIN, LEFT JOIN с обязательным указанием ON.

  • Запрет на SELECT *: В промышленном и аналитическом коде всегда перечисляются только конкретные необходимые столбцы, чтобы исключить скрытые падения моделей и лишнюю нагрузку на ввод-вывод.

  • Единые отступы: Жесткая привязка к 4 пробелам (или 2 пробелам в зависимости от репозитория) без табуляций и выравнивание подчиненных условий AND / OR под основным WHERE.


Сравнение двух доминирующих школ оформления

ПараметрКлассическая школа (ANSI / Болье / учебники)Аналитическая школа (dbt Labs / современный DWH)
Ключевые словаSELECT, FROM, WHERE (ЗАГЛАВНЫЕ)select, from, where (строчные)
ФункцииCOUNT(), ROUND(), COALESCE()count(), round(), coalesce()
Поля и таблицыcustomer_id, rental (строчные)customer_id, rental (строчные)
Сложные выборкиПодзапросы либо CTEСтрого CTE (WITH)
-- Классический стиль (принят в конспекте)
SELECT
    customer_id,
    SUM(amount) AS total_amount
FROM payment
GROUP BY customer_id;

-- Стиль dbt Labs (современный аналитический)
select
    customer_id,
    sum(amount) as total_amount
from payment
group by customer_id;

H3


BETWEEN

оператор диапазона; сначала нижняя граница, затем верхняя 98

SELECT customer_id, rental_date
FROM rental
WHERE rental_date BETWEEN '2005-06-14' AND '2005-06-16';
SELECT rental_id, customer_id, return_date
FROM rental
WHERE return_date NOT BETWEEN '2005-05-01' AND '2005-09-01';

CASE

Expression, оператор условной логики
Проверяет истинность набора условий и в зависимости от результата проверки может возвращать тот или иной результат.

-- Синтаксис
CASE
    WHEN condition1 THEN result1
    WHEN condition2 THEN result2
    ...
    ELSE resultN
END;
-- Basic Case Usage
SELECT product_name,
       CASE
           WHEN stock_quantity > 0 THEN 'In Stock'
           ELSE 'Out of Stock'
       END AS stock_status
FROM products;
-- Multiple Conditions
SELECT employee_name,
       CASE
           WHEN salary > 50000 THEN 'High Salary'
           WHEN salary BETWEEN 30000 AND 50000 THEN 'Medium Salary'
           ELSE 'Low Salary'
       END AS salary_category
FROM employees;
-- Using CASE in ORDER BY
SELECT order_id, order_date
FROM orders
ORDER BY
    CASE
        WHEN order_status = 'Pending' THEN 1
        WHEN order_status = 'Shipped' THEN 2
        ELSE 3
    END;
-- Using CASE in UPDATE
UPDATE employees
SET salary_category = 
    CASE
        WHEN salary > 50000 THEN 'High Salary'
        WHEN salary BETWEEN 30000 AND 50000 THEN 'Medium Salary'
        ELSE 'Low Salary'
    END;

CAST( )

SELECT
    -- Работа с датой и временем
    CAST('2019-09-17 15:30:00' AS DATETIME), --> 2019-09-17 15:30:00
    CAST('2019-09-17 15:30:00' AS DATE),     --> 2019-09-17
    CAST('2019-09-17 15:30:00' AS TIME),     --> 15:30:00

    -- Преобразование в десятичное число с заданной точностью и округлением
    CAST('123.456' AS DECIMAL(5, 2)),        --> 123.46
    CAST(123 AS DECIMAL(5, 2)),              --> 123.00

    -- Преобразование в строку
    CAST(12345 AS CHAR),                     --> '12345'
    CAST('HelloWorld' AS CHAR(5)),           --> 'Hello' (обрежет до 5 символов)
    
    -- Преобразование в целые числа
    CAST(-42.8 AS SIGNED),                   --> -43
    CAST('100' AS UNSIGNED),                 --> 100

    -- Бинарное сравнение (с учетом регистра)
    (CAST('abc' AS BINARY) = 'ABC');         --> 0 (False)
SELECT * FROM rental 
WHERE rental_date < CAST('2005-05-25' AS DATE);

COUNT( )

SELECT c.first_name, c.last_name, count(*)
FROM customer c
  INNER JOIN rental r
  ON c.customer_id = r.customer_id
GROUP BY c.first_name, c.last_name
HAVING count(*) >= 40;

Чтобы не нагружать базу данных, хорошим тоном будет посчитать сначала количество строк, которое попадает под условие:

SELECT COUNT(*) 
FROM large_table
WHERE your_conditions;

CREATE TABLE

Создание таблицы 52

CREATE TABLE person(
    person_id INT PRIMARY KEY AUTO_INCREMENT,
    fname VARCHAR(20),
    lname VARCHAR(20),
    -- ...
    postal_code VARCHAR(20)
);

CREATE TEMPORARY TABLE

Создание временной таблицы 77

CREATE TEMPORARY TABLE actors_J (
    actor_id smallint(5),
    first_name varchar(45),
    last_name varchar(45)
);

INSERT INTO actors_j
SELECT actor_id, first_name, last_name
FROM actor
WHERE last_name LIKE 'J%';

CREATE VIEW

Создание представления (виртуальной таблицы) 78

CREATE VIEW cust_vw AS
SELECT customer_id, first_name, last_name, active
FROM customer;

DATE( )

SELECT DATE('2003-12-31 01:02:03'); --> 2003-12-31
SELECT c.first_name, c.last_name,
  TIME(r.rental_date) rental_time
FROM customer c
  INNER JOIN rental r
  ON c.customer_id = r.customer_id
WHERE DATE(r.rental_date) = '2005-06-14';

DATE_ADD( )

SELECT
    DATE_ADD('2018-05-01', INTERVAL 1 DAY), --> '2018-05-02'
    DATE_ADD('2018-05-01', INTERVAL -1 YEAR), --> '2017-05-01'
    DATE_ADD('2018-12-31 23:59:59',
             INTERVAL 1 DAY), --> '2019-01-01 23:59:59'
    DATE_ADD('2020-12-31 23:59:59',
             INTERVAL 1 SECOND), --> '2021-01-01 00:00:00'
    DATE_ADD('2100-12-31 23:59:59',
             INTERVAL '1:1' MINUTE_SECOND), --> '2101-01-01 00:01:00'
    DATE_ADD('2025-12-31 1:58:59', 
             INTERVAL '23:2:2' HOUR_SECOND), --> '2026-01-01 01:01:01'
    DATE_ADD('2017-01-15', 
             INTERVAL '9-11' YEAR_MONTH); --> '2026-12-15'

DATEDIFF( )

SELECT DATEDIFF('2019-09-03', '2019-06-21'); --> 74

-- Игнорирует время дня в своих аргументах
SELECT DATEDIFF('2019-09-03 23:59:59', '2019-06-21 00:00:01'); --> 74

DELETE

инструкция удалить данные 61, 152

DELETE FROM person
WHERE person_id = 2;
DELETE FROM string_tbl;

DESC

команда (describe) посмотреть столбцы и определение таблицы 53

DESC person;

ключевое слово для сортировки по убыванию 87

ORDER BY last_name desc

DISTINCT

ключевое слово исключить из вывода дубликаты (оставить уникальные) 74

SELECT DISTINCT actor_id
FROM film_actor
ORDER BY actor_id;

DROP TABLE

команда удалить таблицу 66

DROP TABLE person;

EXTRACT

SELECT EXTRACT(YEAR FROM '2019-09-18 22:19:05');  --> 2019
SELECT EXTRACT(MONTH FROM '2019-09-18 22:19:05'); --> 09
SELECT EXTRACT(DAY FROM '2019-09-18 22:19:05');   --> 18

IN

оператор членства 102, 369

WHERE last_name IN ('WILLIAMS', 'DAVIS');
WHERE rating NOT IN ('PG-13', 'R', 'NC-17');

INNER JOIN

внутреннее соединение 117

SELECT c.first_name, c.last_name, a.address
FROM customer c INNER JOIN address a
  ON c.address_id = a.address_id;

Если имена столбцов, используемых для соединения двух таблиц, идентичны, вместо подпредложения ON можно использовать подпредложение USING

SELECT c.first_name, c.last_name, a.address
FROM customer c INNER JOIN address a
  USING (address_id);

INSERT INTO

инструкция добавить данные 57, 146

INSERT INTO person
    (person_id, fname, lname, eye_color, birth_date)
VALUES (null, 'William', 'Turner', 'BR', '1972-05-27');

IS NULL

оператор проверить является ли выражение null 108

SELECT rental_id, customer_id
FROM rental
WHERE return_date IS NULL;
SELECT rental_id, customer_id, return_date
FROM rental
WHERE return_date IS NOT NULL;

LEFT()

встроенная функция для выделения слева 104

SELECT last_name, first_name
FROM customer
WHERE left(last_name, 1) = 'Q';
-- выделение первой буквы столбца last_name

LIKE

оператор членства 103, 155
Используется при условных запросах, когда мы хотим узнать, соответствует ли строка определенному шаблону.

-- Синтаксис
SELECT column1, column2, ...
FROM table_name
WHERE column_name [NOT] LIKE pattern;
SELECT rating FROM film WHERE title LIKE '%PET%';
SELECT name, name LIKE '%y' ends_in_y
FROM category;

REGEXP

оператор принимает регулярное выражение 106

SELECT last_name, first_name
FROM customer
WHERE last_name REGEXP '^[QY]';

SHOW TABLES

команда посмотреть таблицы в базе 65

SHOW TABLES;

SHOW FULL TABLES

команда посмотреть таблицы в базе c выводом типа

SHOW FULL TABLES;

STR_TO_DATE( )

UPDATE rental
SET return_date = STR_TO_DATE('September 17, 2019', '%M', '%d', '%Y')
WHERE rental_id = 99999;

TIME

79

SELECT c.first_name, c.last_name,
  time(r.rental_date) rental_time
FROM customer c
  INNER JOIN rental r
  ON c.customer_id = r.customer_id
WHERE date(r.rental_date) = '2005-06-14';

UPDATE

инструкция изменение (дополнение) данных 61, 157

UPDATE person
SET street = '1225 Tremont St.',
    city = 'Boston',
    state = 'MA',
    country = 'USA',
    postal_code = '02138'
WHERE person_id = 1;

ОПЕРАТОРЫ СРАВНЕНИЯ

=, !=, <, >, <>, LIKE, IN, BETWEEN

ОбозначениеОператорОписание
=РавенствоЕсли оба значения равны, то результат будет равен 1, иначе 0
<=>ЭквивалентностьАналогичен оператору равенства, за исключением того, что результат будет равен 1 в случае сравнения NULL с NULL и 0, когда идёт сравнение любого значения с NULL
<> или !=НеравенствоЕсли оба значения не равны, то результат будет равен 1, иначе 0
<МеньшеЕсли одно значение меньше другого, то результат будет равен 1, иначе 0
<=Меньше или равноЕсли одно значение меньше или равно другому, то результат будет равен 1, иначе 0
>БольшеЕсли одно значение больше другого, то результат будет равен 1, иначе 0
>=Больше или равноЕсли одно значение больше или равно другому, то результат будет равен 1, иначе 0

ЛОГИЧЕСКИЕ ОПЕРАТОРЫ

  • AND – оба условия должны быть верны

  • OR – достаточно, чтобы выполнилось хотя бы одно условие

  • NOT – условие становится противоположным

  • XOR – выполняется только одно из двух условий, но не оба сразу


ПОДСТАНОВОЧНЫЕ СИМВОЛЫ

| Подстановочный символ | Соответствие                         |
| --------------------- | ------------------------------------ |
|  _                    | В точности один символ               |
|  %                    | Любое количество символов, включая 0 |


# Примеры выражений поиска

| Выражение поиска | Интерпретация                                         |
| ---------------- | ----------------------------------------------------- |
| F%               | Строка, начинающаяся с F                              |
| %f               | Строка, заканчивающаяся f                             |
| %bas%            | Строка, содержащая подстроку `bas`                    |
| __t_             | Строка из 4 символов с t в третьей позиции            |
| ___-__-____      | Строка из 11 символов с дефисами в 4-й и 7-й позициях |

СКАЛЯРНЫЕ ФУНКЦИИ

  • Изменение регистра: LOWER, UPPER, INITCAP

  • Работа с длиной и пробелами: LENGTH

  • Извлечение подстрок: LEFT, RIGHT

  • Поиск позиции фрагмента: POSITION

  • Фильтрация по шаблону: LIKE, ILIKE


RTFM

SELECT name, ROUND(salary * 1.2, 2) 
FROM employees 
WHERE department = 'IT';
  • SELECT, FROM, WHERE – это зарезервированные Keywords (ключевые слова);

  • ROUND – это Function (функция), которая принимает аргументы и округляет число до двух знаков после запятой;

  • Строка SELECT name, ROUND(salary * 1.2, 2) – это SELECT Clause (предложение);

  • Строка WHERE department = 'IT' – это WHERE Clause (предложение);

  • Конструкция ROUND(salary * 1.2, 2) – это Expression (выражение). При этом вложенный в неё кусочек salary * 1.2 – это тоже Expression. Одно выражение здесь находится внутри другого и на выходе дает готовое число;

  • Кусочек department = 'IT' – это Predicate (предикат / условие), возвращающий логическое да или нет;

  • Весь запрос целиком – это один большой SELECT Statement (инструкция).

Statement

Инструкция (или Оператор)

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

Инструкция – это предложение в языке SQL, которое обычно заканчивается точкой с запятой ;. Это неделимый блок выполнения: создать объект, удалить данные, подтвердить транзакцию или вернуть результат запроса.


Инструкции делятся на группы: DDL (изменение структуры), DML (изменение данных), DCL (управление правами) и TCL (управление транзакциями).

ALTER TABLE, COMMIT, CREATE INDEX, CREATE TABLE, CREATE VIEW, DEALLOCATE PREPARE, DELETE, DROP INDEX, DROP TABLE, DROP VIEW, EXECUTE, GET DIAGNOSTICS, GRANT, HANDLER, INSERT, LOCK TABLES, PERPARE, RELEASE SAVEPOINT, RENAME TABLE, REPLACE, REVOKE, ROLLBACK, SAVEPOINT, SELECT, SET, SET TRANSACTION, SHOW COLLATION, SHOW ENGINES, SHOW ERRORS, SHOW FUNCTION, SHOW GRANTS, SHOW PRIVILEGES, SHOW PROCEDURE, SHOW, SHOW STATUS, SHOW WARNINGS, SHOW TRANSACTION, TRUNCATE TABLE, UNLOCK TABLES, UPDATE

Clause

Предложение

Подчиненная, составная часть SQL-инструкции (обычно инструкции SELECT, UPDATE или DELETE).

Clause не может существовать сама по себе. Это встроенный инструмент для тонкой настройки или модификации основной инструкции. Предложения всегда начинаются с определенного ключевого слова и определяют, откуда брать данные, как их фильтровать, как группировать или сколько строк возвращать. Например, весь запрос SELECT...WHERE... – это Statement, а его часть WHERE... – это Clause.


  • Statement – это целое, законченное Предложение (с большой буквы и с точкой в конце).

  • Clause – это придаточное предложение (зависимый блок), входящий в состав большого.

SELECT name, salary -- Это SELECT Clause (определяет, ЧТО вернуть)
FROM employees      -- Это FROM Clause (определяет, ОТКУДА взять)
WHERE salary > 50000;-- Это WHERE Clause (определяет, КАК фильтровать)

При этом весь запрос целиком (от слова SELECT до точки с запятой ;) называется SELECT Statement (инструкция или оператор выбора данных).

CHECK OPTION, CONNECT BY, CUBE, DISTINCT ON, FETCH, FILTER, FROM, GROUP BY, HAVING, INNER JOIN, LATERAL, LEFT JOIN, LIMIT, LOCK TABLE, MATCH AGAINST, MERGE, NATURAL JOIN, OFFSET, ORDER BY, OVER, PARTITION BY, PIVOT, RECURSIVE, RETURNING, RIGHT JOIN, POLLUP, TABLESAMPLE, UNION ALL, UNION, UNPIVOT, WHERE, WINDOW, WITH

Keywords

Ключевое слово (или Зарезервированное слово)

Встроенное в синтаксис языка SQL слово, которое имеет фиксированное, заранее определенное значение для парсера (движка) базы данных.

Это кирпичики и служебные команды языка. Нельзя использовать ключевые слова в качестве имен своих таблиц или столбцов (например, нельзя назвать таблицу TABLE или WHERE), иначе СУБД выдаст ошибку. Ключевые слова указывают базе данных, что именно нужно сделать с точки зрения синтаксиса (например: SELECT, FROM, AND, OR, AS, NOT, NULL).

ADD, ALL, AND, ANY, AS, BEETWEEN, BY, DISTINCT, DROP, EXIST, EXPLAIN, IFNULL, IN, INTO, IS NULL, LIKE, NOT, ON, OR, OUTER JOIN, REGEXP, USING, VALUES, WITH CHECK OPTION

Expression

Выражение

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

Если Statement (инструкция) – это целое законченное действие, а Predicate (предикат) – это проверка, которая отвечает только да или нет, то Expression – это вычислимый элемент, который на выходе дает готовые данные (число, строку, дату или массив).


  • 5 – простейшее выражение (константа, возвращает число 5);

  • salary * 1.2 – выражение (умножает значение из столбца на 1.2 и возвращает новую сумму);

  • UPPER(name) – выражение (функция UPPER() обрабатывает строку и возвращает её в верхнем регистре);

  • CASE WHEN ... END – тоже выражение (вычисляет условия и возвращает ровно один итоговый результат).

CASE, COALESCE, DECODE, FORMAT, GREATEST, IF, INET_ATON, INTERVAL, JSON_CONTAINS, JSON_MERGE_PATCH, LEAST, REGEXP_REPLACE, REGEXP_SUBSTR, STRING_AGG, UUID

Function

Функция

Именованный блок готового программного кода, который принимает на вход значения (аргументы), обрабатывает их по заложенному алгоритму и обязательно возвращает результат.

Функции избавляют от написания сложной логики вручную. Они бывают встроенными (предоставленными СУБД, например, для подсчета строк COUNT(), изменения регистра UPPER() или работы с датами NOW()) и пользовательскими (UDF – которые вы пишете сами). Главное отличие функции от ключевого слова – функция выполняет конкретные вычисления над переданными ей данными.

ABS(), AVG(), CEIL(), CONCAT(), COUNT(), CURDATE(), DATE_FORMAT(), EXTRACT(), FLOOR(), GROUP_CONCAT(), INSTR(), JSON_ARRAY(), JSON_EXTRACT(), JSON_OBJECT(), JSON_UNQUOTE(), JSON_VALID(), LAST_DAY(), LENGTH(), LOWER(), LPAD(), MAX(), MIN(), MOD(), NOW(), POWER(), RAND(), ROUND(), RPAD(), STR_TO_DATE(), SUBSTRING(), SUM(), TIMESTAMPDIFF(), TRIM(), UNIX_TIMESTAMP(), UPPER(), WEEK()

Index

Индекс (или Указатель)

Отдельная служебная структура данных в СУБД, создаваемая поверх таблицы для ускорения поиска и сортировки строк.

Индекс работает как алфавитный указатель или оглавление в конце толстой книги. Вместо того чтобы перебирать всю книгу (сканировать всю таблицу на диске), СУБД смотрит в индекс, мгновенно находит физический адрес нужной строки и считывает её.


Индексы значительно ускоряют чтение данных, но замедляют запись, так как СУБД приходится обновлять их при каждом добавлении или изменении строк.

Indexes in MySQL : Adding Index To Table, AUTO_INCREMENT, B-TREE, Clustered, Composite, Covering, Descending, Disabling Index For Bulk Inserts, EXPLAIN ANALYZE For Index Usage, FULLTEXT, HUSH, Identifying Unused Indexes, Index Cardinality, Index Hints, Indexing Impact On DML, Index Usage In JOIN, InnoDB Vs. MyISAM Indexing, JSON Path Indexes, Monitoring Index Usage, ORDER BY With, Partial, PRIMARY KEY, SHOW INDEX, SPITIAL ...

Condition

Condition

Условие (или сравниваемое значение)

Логическое выражение (predicate), которое обязательно возвращает тип данных BOOLEAN (то есть результат вычисления может быть только TRUE, FALSE или NULL/UNKNOWN)

Result

Возвращаемое значение


Predicate

Predicate

Предикат

Логическое выражение, которое оценивает свойства данных и всегда возвращает логическое значение: TRUE, FALSE или NULL/UNKNOWN.


Если Expression (выражение) может возвращать числа, строки или даты, то Predicate возвращает только логический результат да / нет / не знаю. Мы используем предикаты каждый раз, когда пишем условия (например, salary > 50000, name IS NULL или age BETWEEN 18 AND 30).

Конкретное логическое утверждение или проверка


Группы инструкций (DDL, DML, DCL, TCL)

Вся магия SQL строится на том, что все Statements (Инструкции) делятся на четыре ключевые группы в зависимости от того, какую глобальную задачу они решают. Это фундаментальная классификация для любого дата-инженера или аналитика.

ГруппаРасшифровкаЧто делает?Основные команды (Statements)
DDLData Definition LanguageСоздает, изменяет или удаляет структуру базы данных (таблицы, индексы, схемы). Работает с коробками для данных.CREATE TABLE, ALTER TABLE, DROP TABLE, CREATE INDEX, TRUNCATE
DMLData Manipulation LanguageРаботает с самими данными внутри этих структур. Позволяет читать, добавлять, менять или удалять строки.SELECT, INSERT, UPDATE, DELETE
DCLData Control LanguageУправляет правами доступа и безопасностью. Определяет, кто из пользователей что может делать.GRANT (разрешить), REVOKE (отозвать права)
DTLData Transaction LanguageУправляет транзакциями – объединяет несколько команд в одну неделимую группу (пакет), чтобы данные не сломались при ошибке.COMMIT (сохранить), ROLLBACK (откатить изменения), SAVEPOINT

Интересный нюанс: Инструкцию SELECT иногда выделяют в отдельную подгруппу – DQL (Data Query Language – язык запросов). Но чаще её все-таки относят к DML, так как она манипулирует выборкой данных.


SQL Query Order of Execution

Порядок написания и выполнения SQL-запроса

-- Порядок написания

SELECT   -- столбцы для отображения
FROM     -- таблица (-ы), из которой (-ых) нужно извлечь данные
WHERE    -- фильтрация строк
GROUP BY -- разбиение строк на группы
HAVING   -- фильтрация **сгруппированных** строк
ORDER BY -- столбцы для сортировки
-- Порядок выполнения

SELECT -- 7: выборка полей
    e.name,
    d.department_name,
    COUNT(o.id) as order_count
FROM employees e -- 1: определение таблиц
    JOIN departments d ON e.department_id = d.id -- 2: соединения
    LEFT JOIN orders o ON e.id = o.employee_id -- 3: дополнительные соединения
WHERE e.salary > 50000 -- 4: фильтрация
GROUP BY e.id, e.name, d.department_name -- 5: группировка
HAVING COUNT(o.id) > 5 -- 6: фильтрация после группировки
ORDER BY order_count DESC -- 8: сортировка
LIMIT 10; -- 9: ограничение вывода

Absent

Глава 9

IN Операторы in и not in
ALL Оператор all
ANY Оператор any
EXSTS
WITH

Обобщенные табличные выражения (Common Table Expressions, CTE) Ключевое слово: WITH

CTE — это временный именованный результирующий набор данных (виртуальная таблица), который существует только на время выполнения одного основного запроса. Он объявляется в самом начале запроса через предложение WITH.

Зачем нужны CTE (в чём их суперсила):

  1. Читаемость сверху вниз («как рецепт»):
    Вместо «матрешки» из подзапросов в блоке FROM, где запрос приходится читать из глубины наружу, CTE читается естественно — от подготовки исходных ингредиентов к итоговому блюду.

  2. **Переиспользование (DRY — Don’t Repeat Yourself):
    К одной и той же CTE можно обратиться в основном запросе несколько раз (например, сджойнить её саму с собой или использовать в UNION), не дублируя код подзапроса.

  3. Цепочки зависимостей (Chaining):
    Каждое следующее CTE в блоке WITH может обращаться к любому CTE, объявленному выше него в этом же списке.

  4. Рекурсия (WITH RECURSIVE):
    Позволяет обходить иерархии, деревья и графы (например, структуру подчинения начальников и сотрудников или категории товаров с подкатегориями). Базовый анатомический синтаксис (с идеальным выравниванием):

WITH 
first_cte AS (
    -- Шаг 1: готовим первые данные
    SELECT ...
    FROM ...
),

second_cte AS (
    -- Шаг 2: можем использовать данные из first_cte!
    SELECT ...
    FROM first_cte
    WHERE ...
)

-- Шаг 3: финальный SELECT, выдающий результат пользователю
SELECT ...
FROM second_cte
    INNER JOIN other_table ON ...;

Возможно потребуется пробежать по предыдущим главам.

Например, в Главе 9 пришлось вспоминать


Интенсив Simulative https://magus1968.github.io/learning-sql/simulative/

DATE – Типизированный литерал
Если следовать правилу Явное лучше неявного:
Вместо '2021-01-01' профессионально использовать типизированный литерал стандарта SQL: DATE '2021-01-01'