Перейти к основному содержимому

Справочник по SQL


Базис: Операторы — оператор, операнд и приоритет в коде; полезно перед условиями в запросах и логикой селекторов.

Синтаксис, операторы, команды клиента и ограничения SQL. Учебный курс: раздел. Пошаговые примеры на схеме магазина — SQL — реальные кейсы.

Полный список команд. Для старта с нуля удобнее компактные таблицы в учебных главах — порядок выполнения SELECT, конструкции чтения, агрегаты, типы JOIN, DDL/DML/TCL.


Полное API SQL (алфавитный указатель)​

Ниже — расширенный список SQL-команд, операторов и функций с кратким смыслом. Это быстрый справочник, который удобно читать по ключевому слову.

A​

  • AND — логическое И.
  • AS — псевдоним столбца/таблицы.
  • AVG — среднее арифметическое.
  • ABS — модуль числа.
  • ALTER TABLE — изменение структуры таблицы.
  • ADD COLUMN — добавление столбца.

B​

  • BETWEEN — выбор значений из диапазона.

C​

  • COUNT — подсчёт записей.
  • CASE — условный выбор значения.
  • COALESCE — первое не-NULL значение.
  • CEILING — округление вверх.
  • CONCAT — склейка строк.
  • CONCAT_WS — склейка строк с разделителем.
  • CHAR_LENGTH — длина строки в символах.
  • CURRENT_DATE — текущая дата.
  • CURRENT_TIME — текущее время.
  • CURDATE — дата сейчас (MySQL).
  • CURTIME — время сейчас (MySQL).
  • CURRENT_TIMESTAMP — текущий timestamp.
  • CROSS JOIN — декартово произведение.
  • CREATE DATABASE — создание БД.
  • CREATE TABLE — создание таблицы.
  • CREATE INDEX — создание индекса.
  • COMMIT — фиксация изменений транзакции.

D​

  • DELETE — удаление записей.
  • DISTINCT — уникальные значения.
  • DAY — день из даты.
  • DAYOFMONTH — день месяца.
  • DATE — дата из datetime/timestamp.
  • DAYOFWEEK — день недели (номер).
  • DAYNAME — день недели (название).
  • DAYOFYEAR — номер дня в году.
  • DATE_FORMAT — форматирование даты.
  • DATE_ADD — сложение даты и интервала.
  • DATE_SUB — вычитание интервала из даты.
  • DATEDIFF — разница дат в днях.
  • DROP DATABASE — удаление БД.
  • DROP TABLE — удаление таблицы.
  • DROP COLUMN — удаление столбца.
  • DROP INDEX — удаление индекса.
  • DESCRIBE — структура таблицы.

E​

  • EXISTS — проверка наличия строк в подзапросе.
  • ELT — строка по номеру из списка аргументов.
  • EXTRACT — извлечение части даты/времени.
  • EXPLAIN — план выполнения запроса.

F​

  • FLOOR — округление вниз.
  • FIELD — номер значения в списке.
  • FIND_IN_SET — поиск в строковом списке.
  • FROM_DAYS — преобразование дней в дату.
  • FOREIGN KEY — внешний ключ.

G​

  • GREATEST — максимум из значений.
  • GROUP_CONCAT — объединение значений группы в строку.
  • GROUP BY — группировка.

H​

  • HOUR — часы из даты/времени.
  • HAVING — фильтрация после группировки.

I​

  • INSERT — вставка записей.
  • IN — принадлежность набору.
  • IS NOT NULL — значение не равно NULL.
  • IS NULL — значение равно NULL.
  • IFNULL — подмена NULL.
  • INSERT SELECT — вставка результата SELECT.
  • INSERT IGNORE — вставка без конфликта (MySQL).
  • INSTR — позиция подстроки.
  • INTERVAL — интервал дат/времени.
  • INNER JOIN — внутренний JOIN.

J​

  • JOIN — соединение таблиц.

L​

  • LIMIT — ограничение выборки.
  • LIKE — поиск по шаблону.
  • LEAST — минимум из значений.
  • LOCATE — поиск позиции подстроки.
  • LEFT — N символов слева.
  • LPAD — дополнение строки слева.
  • LOWER — нижний регистр.
  • LCASE — синоним LOWER.
  • LTRIM — обрезание пробелов слева.
  • LENGTH — длина строки.
  • LEFT JOIN — левый JOIN.

M​

  • MIN — минимальное значение.
  • MAX — максимальное значение.
  • MOD — остаток от деления.
  • MID — подстрока (синоним SUBSTRING в MySQL).
  • MONTH — месяц из даты.
  • MINUTE — минуты из даты/времени.
  • MONTHNAME — название месяца.
  • MODIFY COLUMN — изменение столбца.

N​

  • NOT — отрицание.
  • NULLIF — возвращает NULL при совпадении значений.
  • NOW — текущие дата и время.

O​

  • OR — логическое ИЛИ.
  • ORDER BY — сортировка.
  • OFFSET — смещение строк.
  • ON DUPLICATE KEY UPDATE — upsert по ключу (MySQL).
  • ON — условие соединения таблиц.

P​

  • POW — степень числа.
  • POSITION — поиск подстроки.
  • PERIOD_ADD — добавление месяцев.
  • PERIOD_DIFF — разница месяцев.
  • PRIMARY KEY — первичный ключ.

R​

  • REPLACE INTO — замена/вставка записи (MySQL).
  • ROUND — округление числа.
  • RAND — случайное число.
  • REPLACE — замена подстроки.
  • RIGHT — N символов справа.
  • RPAD — дополнение строки справа.
  • REVERSE — разворот строки.
  • REPEAT — повтор строки.
  • RTRIM — обрезание пробелов справа.
  • REGEXP — фильтрация по regex.
  • RIGHT JOIN — правый JOIN.
  • RENAME TABLE — переименование таблицы.
  • ROLLBACK — откат транзакции.

S​

  • SELECT — получение записей.
  • SUM — сумма.
  • SIGN — знак числа.
  • SQRT — квадратный корень.
  • SUBSTRING — взятие подстроки.
  • SUBSTRING_INDEX — часть строки по разделителю.
  • SPACE — строка из пробелов.
  • SECOND — секунды из времени.
  • SEC_TO_TIME — секунды в TIME.
  • STR_TO_DATE — строка в дату.
  • SELECT INTO — копирование результата выборки в таблицу/переменную (по диалекту).
  • START TRANSACTION — начало транзакции.
  • SAVEPOINT — промежуточная точка отката.
  • SELECT ... FOR UPDATE — блокировка строк на обновление.
  • SHOW TABLES — список таблиц.
  • SHOW COLUMNS — столбцы таблицы.
  • SHOW INDEX — индексы таблицы.
  • SHOW CREATE TABLE — SQL создания таблицы.

T​

  • TRUNCATE — усечение числа.
  • TRIM — обрезание пробелов/символов.
  • TIME_FORMAT — форматирование времени.
  • TO_DAYS — дата в дни.
  • TIME_TO_SEC — время в секунды.
  • TIMESTAMPDIFF — разница дат/времени по единице измерения.
  • TRUNCATE TABLE — очистка таблицы.

U​

  • UPDATE — редактирование записей.
  • UPPER — верхний регистр.
  • UCASE — синоним UPPER.
  • USING — соединение по одноимённым столбцам.
  • UNION — объединение с удалением дублей.
  • UNION ALL — объединение без удаления дублей.
  • USE — выбор базы данных.
  • UNIQUE — ограничение уникальности.

W​

  • WHERE — условие фильтрации.
  • WEEKDAY — день недели.
  • WEEK — номер недели в году.

Y​

  • YEAR — год из даты.
  • YEARWEEK — год и номер недели.
Важно про диалекты SQL

Часть операторов и функций зависит от диалекта — MySQL, PostgreSQL, SQL Server, Oracle. Используйте этот список как карту по терминам и сверяйте точный синтаксис с документацией вашей СУБД.


Справочные таблицы​

Справочник SQL​

Версия: ANSI SQL:2016 (с учётом общепринятых расширений)


1. DDL — Data Definition Language​

Операции определения и модификации структуры данных.


CREATE​

Создание объектов БД.


Таблица​
CREATE TABLE [IF NOT EXISTS] table_name (
column_name data_type [CONSTRAINT constraint_name] [column_constraint],
...,
[table_constraint]
);
  • IF NOT EXISTS — в PostgreSQL/MySQL/SQLite в заголовке CREATE TABLE; в T-SQL — отдельная проверка:
-- PostgreSQL / MySQL / SQLite
CREATE TABLE IF NOT EXISTS employees (...);

-- SQL Server
IF NOT EXISTS (
SELECT 1 FROM sys.tables WHERE name = N'employees' AND schema_id = SCHEMA_ID(N'dbo')
)
CREATE TABLE dbo.employees (...);
  • column_constraint:
    NOT NULL, NULL, UNIQUE, PRIMARY KEY, CHECK (condition), DEFAULT value, REFERENCES ref_table (col) [ON DELETE | UPDATE action]
  • table_constraint:
    PRIMARY KEY (col1, col2), FOREIGN KEY (col) REFERENCES ..., UNIQUE (col), CHECK (condition)

Индекс​
CREATE [UNIQUE] INDEX [IF NOT EXISTS] index_name
ON table_name (column_name [ASC | DESC] [, ...])
[INCLUDE (included_column, ...)] -- T-SQL, PostgreSQL 11+
[WHERE condition]; -- filtered index: T-SQL, PostgreSQL (partial index)

Представление​
CREATE [OR REPLACE] [TEMP | TEMPORARY] VIEW view_name [(alias_col, ...)] AS
SELECT ...;
-- WITH [LOCAL | CASCADE] CHECK OPTION — в ANSI, поддерживается в PostgreSQL, Oracle

Схема​
CREATE SCHEMA [IF NOT EXISTS] schema_name
[AUTHORIZATION user_name];

Домен (PostgreSQL, Firebird)​
CREATE DOMAIN domain_name AS base_type
[CONSTRAINT constraint_name] [CHECK (condition)];

Последовательность (serial, identity support)​

Код ITЗагрузка примера кода…


Тип данных (PostgreSQL, Oracle)​
CREATE TYPE type_name AS (
field_name data_type,
...
);

-- Или ENUM:
CREATE TYPE enum_name AS ENUM ('val1', 'val2', ...);

Триггер (общая форма)​
CREATE [OR REPLACE] TRIGGER trigger_name
{BEFORE | AFTER | INSTEAD OF} {event [, ...]}
ON table_name
[REFERENCING {OLD [AS] old_alias | NEW [AS] new_alias}]
[FOR EACH {ROW | STATEMENT}]
[WHEN (condition)]
EXECUTE {FUNCTION function_name() | PROCEDURE proc_name()};
-- event: INSERT, UPDATE [OF col], DELETE
-- Поддержка: Oracle (PL/SQL), PostgreSQL (PL/pgSQL), SQL Server (T-SQL, но синтаксис отличается)

ALTER​

Изменение объектов.


Таблица​
ALTER TABLE table_name
ADD [COLUMN] column_name data_type [column_constraint],
DROP [COLUMN] column_name [CASCADE | RESTRICT],
ALTER [COLUMN] column_name {SET ДАННЫЕ TYPE new_type | SET DEFAULT value | DROP DEFAULT | SET NOT NULL | DROP NOT NULL},
ADD CONSTRAINT constraint_name constraint_definition,
DROP CONSTRAINT constraint_name [CASCADE],
RENAME COLUMN old_name TO new_name, -- PostgreSQL, SQLite
RENAME TO new_table_name; -- PostgreSQL, Oracle
  • В T-SQL:
ALTER TABLE dbo.Orders ALTER COLUMN amount DECIMAL(18,2) NOT NULL;
ALTER TABLE dbo.Orders DROP COLUMN legacy_code;
EXEC sp_rename 'dbo.Orders.old_col', 'new_col', 'COLUMN';

Индекс / представление / последовательность​
ALTER INDEX index_name RENAME TO new_name; -- PostgreSQL
ALTER SEQUENCE seq_name [RESTART [WITH value] | ...];
-- Для представлений: обычно DROP + CREATE или CREATE OR REPLACE

DROP​

Удаление объектов.

DROP TABLE [IF EXISTS] table_name [CASCADE | RESTRICT];
DROP INDEX [IF EXISTS] index_name;
DROP VIEW [IF EXISTS] view_name [CASCADE];
DROP SCHEMA [IF EXISTS] schema_name [CASCADE | RESTRICT];
DROP SEQUENCE [IF EXISTS] sequence_name [CASCADE];
DROP TYPE [IF EXISTS] type_name [CASCADE];
DROP TRIGGER [IF EXISTS] trigger_name ON table_name;
-- CASCADE: рекурсивно удаляет зависимые объекты (например, FK, views)
-- RESTRICT (по умолчанию в ANSI): запрещает удаление при наличии зависимостей
-- IF EXISTS — поддерживается в PostgreSQL, MySQL, SQLite; в T-SQL — `IF OBJECT_ID('name','U') IS NOT NULL DROP TABLE ...`

TRUNCATE​

Быстрая очистка таблицы (не DML!).

TRUNCATE TABLE table_name
[RESTART IDENTITY] -- сброс сиквенсов, связанных с IDENTITY/serial (PostgreSQL, T-SQL)
[IDENTITY RESTART] -- T-SQL синоним
[CONTINUE IDENTITY] -- T-SQL: не сбрасывать
[CASCADE]; -- рекурсивно для дочерних таблиц (PostgreSQL)
-- Не вызывает триггеры DELETE (в большинстве СУБД)
-- Не может быть отменён отдельно в рамках транзакции в некоторых СУБД без explicit BEGIN

RENAME (не ANSI, но широко используется)​
-- PostgreSQL, SQLite
ALTER TABLE old_name RENAME TO new_name;
ALTER TABLE table_name RENAME COLUMN old_col TO new_col;

-- Oracle
RENAME old_name TO new_name;

-- MySQL
RENAME TABLE old_name TO new_name;
ALTER TABLE table_name RENAME COLUMN old_col TO new_col; -- ≥8.0.3

2. DML — Data Manipulation Language​

Работа с данными.


INSERT​

Код ITЗагрузка примера кода…


3. DCL — Data Control Language​

Управление доступом и привилегиями.


GRANT​

Код ITЗагрузка примера кода…


REVOKE​
REVOKE [GRANT OPTION FOR] privilege [, ...] ON object_type object_name
FROM {user | role} [, ...]
[CASCADE | RESTRICT];

-- CASCADE: отзывает привилегию и у тех, кому она была передана этим пользователем (если WITH GRANT OPTION был использован)
-- RESTRICT (по умолчанию): запрещает отозвать, если привилегия была передана дальше
-- Отзыв всех:
REVOKE ALL PRIVILEGES ON TABLE employees FROM analyst;

CREATE ROLE / DROP ROLE (не ANSI, но стандарт де-факто)​
CREATE ROLE role_name [WITH option [, ...]];
-- PostgreSQL: LOGIN, SUPERUSER, CREATEDB, CREATEROLE, INHERIT, REPLICATION, CONNECTION LIMIT n, PASSWORD 'pwd', VALID UNTIL 'timestamp'
-- SQL Server: CREATE LOGIN, CREATE USER, ALTER ROLE role_name ADD MEMBER user

DROP ROLE [IF EXISTS] role_name;

⚠️ В T-SQL управление доступом разделено (сервер → БД → роль):

CREATE LOGIN app_login WITH PASSWORD = '...';
CREATE USER app_user FOR LOGIN app_login;
ALTER ROLE db_datareader ADD MEMBER app_user;
-- DENY имеет приоритет над GRANT

4. TCL — Transaction Control Language​

Управление транзакциями.


BEGIN / START TRANSACTION​
-- ANSI:
START TRANSACTION [ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE}]
[READ {ONLY | WRITE}];

-- PostgreSQL, MySQL:
BEGIN [WORK | TRANSACTION];
-- Необязательно — в большинстве СУБД DML-команды неявно запускают транзакцию, если autocommit = OFF.

-- T-SQL:
BEGIN TRANSACTION [transaction_name];
-- Можно вкладывать (savepoints под капотом), но commit/rollback действуют на весь блок, если не указано savepoint.

COMMIT​
COMMIT [WORK | TRANSACTION]; -- ANSI
-- T-SQL: COMMIT [TRANSACTION [name]]
-- PostgreSQL: COMMIT AND CHAIN — продолжает новую транзакцию

ROLLBACK​
ROLLBACK [WORK | TRANSACTION]; -- откат всей транзакции
ROLLBACK [WORK | TRANSACTION] TO [SAVEPOINT] savepoint_name;

SAVEPOINT​
SAVEPOINT savepoint_name;
-- В T-SQL: SAVE TRANSACTION savepoint_name
-- Откат к точке:
ROLLBACK TO savepoint_name; -- ANSI, PostgreSQL
ROLLBACK TRANSACTION savepoint_name; -- T-SQL

-- Удаление точки (необязательно, удаляются при COMMIT/ROLLBACK):
RELEASE SAVEPOINT savepoint_name; -- PostgreSQL
-- В T-SQL точка остаётся до конца транзакции.

Уровни изоляции (стандартные и поведение)​
УровеньDirty ReadNon-Repeatable ReadPhantom ReadСериализуемость
READ UNCOMMITTEDдададанет
READ COMMITTEDнетдаданет
REPEATABLE READнетнетзависит¹нет
SERIALIZABLEнетнетнетда

¹ — в PostgreSQL REPEATABLE READ предотвращает phantom reads за счёт snapshot isolation; в SQL Server — нет (требуется SERIALIZABLE).


5. DQL — Data Query Language​

Извлечение данных. Основной оператор — SELECT.


Обобщённый синтаксис (логический порядок обработки)​

Код ITЗагрузка примера кода…

🔹 Физический порядок выполнения:
FROM → JOIN → WHERE → GROUP BY → HAVING → SELECT → DISTINCT → WINDOW → ORDER BY → LIMIT/FETCH.


FROM и JOIN​
Типы JOIN (ANSI)​
ТипСинтаксисПримечание
Внутреннее соединениеINNER JOIN или JOINТолько совпадающие строки
Левое внешнееLEFT [OUTER] JOINВсе строки из левой таблицы
Правое внешнееRIGHT [OUTER] JOINВсе строки из правой таблицы
Полное внешнееFULL [OUTER] JOINВсе строки из обеих таблиц
Перекрёстное (декартово)CROSS JOINБез условия — полное произведение
Самосоединениеtable t1 JOIN table t2 ON ...Та же таблица, разные алиасы

Расширения​
  • LATERAL (PostgreSQL, Oracle 12c+, SQL Server APPLY):
SELECT *
FROM employees e
LEFT JOIN LATERAL (
SELECT * FROM salaries s
WHERE s.emp_id = e.id
ORDER BY s.effective_date DESC
LIMIT 1
) AS latest_sal ON true;
  • T-SQL OUTER APPLY / CROSS APPLY — аналог LATERAL:
SELECT *
FROM employees e
OUTER APPLY (
SELECT TOP 1 * FROM salaries s
WHERE s.emp_id = e.id
ORDER BY s.effective_date DESC
) AS latest_sal;

WHERE​

Фильтрация строк до группировки.
Поддерживает:

  • Сравнения (=, <>, <, >, <=, >=, !=)
  • Логические (AND, OR, NOT)
  • BETWEEN a AND b — включительно
  • IN (val1, val2, ...) / NOT IN (...)
  • LIKE 'pattern' / ILIKE (PostgreSQL, case-insensitive)
    % — любое кол-во символов, _ — ровно один
  • SIMILAR TO (PostgreSQL, SQL:2008) — регулярные выражения (ограниченные)
  • ~, ~*, !~, !~* (PostgreSQL — полноценные regex)
  • IS [NOT] NULL
  • EXISTS (subquery)
  • ANY / SOME / ALL с подзапросами:
    value > ALL (SELECT ...) — строго больше любого

GROUP BY​

Группировка строк. Требует агрегации для всех неключевых колонок в SELECT.


Агрегатные функции (стандартные)​
ФункцияОписание
COUNT(*)число строк (включая NULL)
COUNT(col)число ненулевых значений в col
SUM(col), AVG(col)сумма, среднее (только числовые)
MIN(col), MAX(col)мин/макс (работает с датами, строками)
ARRAY_AGG(col)PostgreSQL: массив значений
STRING_AGG(col, delimiter)PostgreSQL/SQL Server: строка через разделитель
GROUP_CONCAT(col SEPARATOR delim)MySQL — аналог
BOOL_AND(col), BOOL_OR(col)PostgreSQL: логические агрегаты
JSON_AGG(col)PostgreSQL/MySQL 5.7+: JSON-массив
JSON_OBJECT_AGG(k, v)PostgreSQL/MySQL: JSON-объект

GROUPING SETS, ROLLUP, CUBE (ANSI, PostgreSQL, SQL Server, Oracle)​
-- GROUPING SETS: явное перечисление групп
SELECT dept, region, SUM(sales)
FROM t
GROUP BY GROUPING SETS ( (dept, region), (dept), (region), () );

-- ROLLUP: иерархическая агрегация (сверху вниз)
GROUP BY ROLLUP (A, B, C)
-- эквивалентно: (A,B,C), (A,B), (A), ()

-- CUBE: все комбинации
GROUP BY CUBE (A, B)
-- эквивалентно: (A,B), (A), (B), ()

GROUPING() — идентификатор уровня агрегации​
SELECT
GROUPING(dept) AS g_dept,
dept,
SUM(sales)
FROM t
GROUP BY ROLLUP (dept);
-- g_dept = 1, если dept — NULL из агрегата ("итоговая" строка)

HAVING​

Фильтрация после группировки. Допускает агрегаты:

SELECT dept, AVG(salary)
FROM employees
GROUP BY dept
HAVING COUNT(*) > 5 AND AVG(salary) > 70000;

WINDOW и оконные функции​
Объявление окна​
SELECT
emp_id,
salary,
AVG(salary) OVER w AS dept_avg,
ROW_NUMBER() OVER w AS rn
FROM employees
WINDOW w AS (PARTITION BY dept_id ORDER BY salary DESC);

Стандартные оконные функции​
КатегорияФункции
РанжированиеROW_NUMBER(), RANK(), DENSE_RANK(), NTILE(n)
АгрегатныеSUM(), AVG(), MIN(), MAX(), COUNT() — с OVER
СмещенияLAG(col, offset, default), LEAD(col, offset, default), FIRST_VALUE(), LAST_VALUE(), NTH_VALUE(col, n)
СтатистическиеPERCENT_RANK(), CUME_DIST(), PERCENTILE_CONT(frac), PERCENTILE_DISC(frac)

Спецификация окна​
OVER (
[PARTITION BY expr, ...]
[ORDER BY expr [ASC | DESC] [NULLS {FIRST | LAST}]]
[frame_clause]
)
-- frame_clause:
-- RANGE | ROWS | GROUPS
-- { UNBOUNDED PRECEDING | CURRENT ROW | offset PRECEDING | offset FOLLOWING }
-- [BETWEEN start AND end]
-- Например:
-- ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING
-- RANGE BETWEEN INTERVAL '1' DAY PRECEDING AND CURRENT ROW -- для временных типов

⚠️ RANGE интерпретирует смещение по значению, ROWS — по числу строк.
Пример (все строки за последний час относительно текущей):

ORDER BY ts
RANGE BETWEEN INTERVAL '1 hour' PRECEDING AND CURRENT ROW

SELECT расширения​
DISTINCT ON (PostgreSQL)​
SELECT DISTINCT ON (dept_id) dept_id, emp_id, hire_date
FROM employees
ORDER BY dept_id, hire_date DESC; -- обязательно ORDER BY по ключу DISTINCT ON
-- Возвращает первую строку в каждой группе dept_id

TOP (T-SQL), LIMIT (ANSI/PostgreSQL/MySQL), FETCH (ANSI)​
-- T-SQL:
SELECT TOP 10 * FROM orders ORDER BY total DESC;
SELECT TOP 10 PERCENT * FROM orders ORDER BY total DESC;

-- ANSI / PostgreSQL ≥8.4 / SQL Server ≥2012:
SELECT * FROM orders
ORDER BY total DESC
FETCH FIRST 10 ROWS ONLY;

-- С пропуском:
OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY;

FOR UPDATE, FOR SHARE​
-- Блокировка строк для обновления (PostgreSQL, Oracle):
SELECT * FROM accounts WHERE id = 1 FOR UPDATE;

-- T-SQL: использует табличные хинты:
SELECT * FROM accounts WITH (UPDLOCK, ROWLOCK) WHERE id = 1;

-- SKIP LOCKED / NOWAIT (PostgreSQL, MySQL 8+):
SELECT * FROM queue FOR UPDATE SKIP LOCKED; -- пропустить занятые строки
SELECT * FROM queue FOR UPDATE NOWAIT; -- ошибка, если строка занята

-- Пакетный захват в одной транзакции — см. [Блокировки в PostgreSQL](./110.md#skip-locked-paket)

6. Системные / служебные команды (не ANSI, но критичны)​

Получение метаданных​
# PostgreSQL (psql)
\dt
\d+ orders
-- PostgreSQL
SELECT table_name FROM information_schema.tables
WHERE table_schema = 'public';

-- MySQL
SHOW TABLES;
DESCRIBE orders;

-- SQL Server
EXEC sp_help 'dbo.Orders';

-- Oracle
SELECT table_name FROM user_tables;
СУБДКлиент / каталог
PostgreSQL\dt, \d, information_schema, pg_catalog
MySQLSHOW, DESCRIBE, information_schema
SQL Serversp_help, sys.*
Oracleuser_*, all_*, dba_*

Управление сессиями / настройками​
-- ANSI: SET [SESSION | LOCAL] parameter = value;
SET TIME ZONE 'UTC';
SET search_path TO myschema, public; -- PostgreSQL
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;

-- T-SQL:
SET NOCOUNT ON;
SET ANSI_NULLS ON;
SET QUOTED_IDENTIFIER ON;

Условное выполнение (в скриптах)​
  • PostgreSQL:
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_tables WHERE tablename = 'logs') THEN
CREATE TABLE logs (...);
END IF;
END $$;
  • T-SQL:
IF NOT EXISTS (SELECT * FROM sys.objects WHERE name = 'logs' AND type = 'U')
CREATE TABLE logs (...);

7. CTE — Common Table Expressions​

Временные именованные результаты запроса, существующие только в рамках одного SELECT/INSERT/UPDATE/DELETE/MERGE.


Базовый синтаксис​
WITH cte_name [(col_alias, ...)] AS (
SELECT ...
)
SELECT ... FROM cte_name;

Особенности​
  • Можно объявлять несколько CTE через запятую:
WITH
sales_2024 AS (SELECT * FROM sales WHERE year = 2024),
top_customers AS (SELECT cust_id, SUM(amount) AS total FROM sales_2024 GROUP BY cust_id HAVING SUM(amount) > 10000)
SELECT c.name, tc.total
FROM customers c
JOIN top_customers tc ON c.id = tc.cust_id;
  • CTE могут ссылаться друг на друга только вперёд (последовательно).
  • В PostgreSQL 12+ после AS можно указать подсказку планировщику
    • MATERIALIZED — выполнить CTE один раз и сохранить результат
    • NOT MATERIALIZED — предпочесть встраивание CTE в основной запрос
    • Подробный разбор с примерами — CTE и материализация в PostgreSQL
WITH cte AS MATERIALIZED (SELECT ...) ...
WITH cte AS NOT MATERIALIZED (SELECT ...) ...

Рекурсивные CTE (WITH RECURSIVE)​

Код ITЗагрузка примера кода…

  • Обязательно UNION ALL (в ANSI; UNION не разрешён в рекурсивной части).
  • В PostgreSQL/SQL Server — лимиты на сессию перед тяжёлым рекурсивным запросом:
-- PostgreSQL
SET work_mem = '256MB';
SET statement_timeout = '30s';

-- T-SQL
OPTION (MAXRECURSION 100);
  • Для предотвращения зацикливания:
    • PostgreSQL ≥14: SEARCH BREADTH FIRST BY id SET ordercol, CYCLE id SET is_cycle TO 'Y' DEFAULT 'N' USING pathcol
    • Oracle: CONNECT BY NOCYCLE
    • T-SQL: OPTION (MAXRECURSION n) (макс. 32767)

8. Подзапросы​

Типы​
ТипОписаниеПример
СкалярныйВозвращает одно значение (одна строка, один столбец)SELECT name, (SELECT AVG(salary) FROM employees) AS dept_avg FROM employees
КоррелированныйСсылается на внешний запросSELECT name FROM employees e WHERE salary > (SELECT AVG(salary) FROM employees WHERE dept_id = e.dept_id)
Табличный (в FROM)Возвращает таблицуSELECT * FROM (SELECT dept_id, AVG(salary) AS avg_sal FROM employees GROUP BY dept_id) AS dept_stats
Существование (EXISTS)Проверяет наличие строкSELECT name FROM departments d WHERE EXISTS (SELECT 1 FROM employees e WHERE e.dept_id = d.id)

Оптимизация​
  • EXISTS предпочтительнее IN при работе с NULL (в IN NULL "отравляет" результат: value NOT IN (a, NULL) → UNKNOWN).
  • NOT EXISTS надёжнее NOT IN.
  • Подзапросы в SELECT (скалярные) могут вызывать N+1 — лучше заменять JOIN или оконными функциями.

9. Множественные операции​

Объединение результатов нескольких SELECT с одинаковой структурой.

ОператорANSIPostgreSQLSQL ServerMySQLЗамечание
Объединение без дубликатовUNION✓✓✓Сортирует для удаления дублей
Объединение с дубликатамиUNION ALL✓✓✓Быстрее, не сортирует
ПересечениеINTERSECT✓✓≤8.0.31: нетУдаляет дубли
Пересечение с дублямиINTERSECT ALL✓✓—
РазностьEXCEPT✓MINUS (Oracle)EXCEPTУдаляет дубли
Разность с дублямиEXCEPT ALL✓——

Синтаксис​
query1
UNION [ALL]
query2
[UNION [ALL] query3 ...]
[ORDER BY ...] -- только в конце всего выражения
[LIMIT ...];

Важно​
  • Порядок столбцов и их типы должны быть совместимы (не обязательно идентичны — INTEGER и BIGINT совместимы).
  • Имена столбцов берутся из первого SELECT.
  • ORDER BY внутри отдельного SELECT недопустим без LIMIT (и то — только в PostgreSQL с OFFSET 0 или LIMIT ALL для эмуляции).

10. Работа с JSON​

Стандарт SQL:2016 (JSON_VALUE, JSON_QUERY, JSON_TABLE)​

Код ITЗагрузка примера кода…


MySQL​
SELECT JSON_EXTRACT(doc, '$.user.name') -- возвращает JSON-значение ("Timur")
SELECT doc->'$.user.name' -- синтаксический сахар
SELECT doc->>'$.user.name' -- как строка: Timur
SELECT JSON_UNQUOTE(JSON_EXTRACT(...)) -- аналог ->>
SELECT * FROM JSON_TABLE(...);

11. Полнотекстовый поиск​

PostgreSQL (tsvector, tsquery)​

Код ITЗагрузка примера кода…


MySQL (FULLTEXT)​
ALTER TABLE articles ADD FULLTEXT(title, content);
SELECT *, MATCH(title, content) AGAINST('SQL база данных' IN NATURAL LANGUAGE MODE) AS score
FROM articles
WHERE MATCH(title, content) AGAINST('SQL база данных');
-- Режимы: NATURAL LANGUAGE, BOOLEAN, WITH QUERY EXPANSION

SQL Server (CONTAINS, FREETEXT)​
-- Требует полнотекстового каталога и индекса
SELECT * FROM articles
WHERE CONTAINS((title, content), 'FORMSOF(INFLECTIONAL, "develop") AND "database"');

12. Хранимые модули​

CREATE FUNCTION​

Код ITЗагрузка примера кода…


Параметры​
  • IN (по умолчанию) — входной
  • OUT — выходной (только в процедурах)
  • INOUT — вход/выход
  • VARIADIC (PostgreSQL) — для массивов: VARIADIC arr INT[]

13. Вспомогательные конструкции​

CASE​
-- Простой CASE (по значению)
CASE col
WHEN 1 THEN 'один'
WHEN 2 THEN 'два'
ELSE 'много'
END

-- Поисковый CASE (по условию)
CASE
WHEN salary < 30000 THEN 'низкий'
WHEN salary BETWEEN 30000 AND 70000 THEN 'средний'
ELSE 'высокий'
END

Функции обработки NULL​
ФункцияОписаниеANSIПример
COALESCE(a, b, c)возвращает первый ненулевой аргумент✓COALESCE(phone, email, 'нет контакта')
NULLIF(a, b)возвращает NULL, если a = b, иначе a✓NULLIF(value, 0) — избежать деления на 0
ISNULL(a, b)T-SQL: аналог COALESCE, но только 2 аргумента—ISNULL(name, '—')
NVL(a, b)Oracle: аналог COALESCE (2 аргумента)—NVL(salary, 0)

Функции сравнения​
ФункцияОписание
GREATEST(a, b, c)максимум из аргументов (PostgreSQL, MySQL, Oracle)
LEAST(a, b, c)минимум
IIF(cond, true_val, false_val)T-SQL: инлайновый CASE

Приведение типов​
CAST(expr AS type)
expr::type -- PostgreSQL, Redshift
TRY_CAST(expr AS type) -- T-SQL, возвращает NULL при ошибке
CONVERT(type, expr [, style]) -- T-SQL (style для дат/строк)

Генерация данных​
-- PostgreSQL: generate_series
SELECT generate_series(1, 10) AS n;
SELECT generate_series('2025-01-01'::DATE, '2025-12-31'::DATE, '1 day'::INTERVAL);

-- T-SQL: рекурсивный CTE или tally-таблица
WITH nums(n) AS (
SELECT 1 UNION ALL SELECT n+1 FROM nums WHERE n < 10
)
SELECT n FROM nums;

14. Сравнение диалектов​

Фича / СУБДPostgreSQL (PL/pgSQL)SQL Server (T-SQL)Oracle (PL/SQL)MySQL
Идентификаторы"quoted"[quoted] или "quoted""quoted"`quoted`
Комментарии--, /* */, /&#42;&#42;/--, /* */--, /* */-- , #, /* */
АвтоинкрементSERIAL, GENERATED ALWAYS AS IDENTITYIDENTITY(1,1), SEQUENCEIDENTITY, SEQUENCE + TRIGGERAUTO_INCREMENT
Строка → числоCAST('123' AS INT)CAST('123' AS INT), TRY_CASTTO_NUMBER('123')CAST('123' AS SIGNED)
Дата/время'2025-11-18'::DATE, timestamptzGETDATE(), SYSDATETIME(), DATETIME2SYSDATE, TIMESTAMP WITH TIME ZONENOW(), CURDATE(), DATETIME(6)
Оконные ф-цииполная поддержка ANSIполная (с 2012)полнаяс 8.0
Рекурсивные CTEWITH RECURSIVEWITH, без RECURSIVEWITH, без RECURSIVEс 8.0
Динамический SQLEXECUTE format('...', arg)EXEC sp_executesql @sql, @params, @p1=...EXECUTE IMMEDIATEPREPARE, EXECUTE, EXECUTE IMMEDIATE
Обработка исключенийEXCEPTION WHEN ... THENBEGIN TRY ... END TRY BEGIN CATCHEXCEPTION WHEN ... THENDECLARE EXIT HANDLER FOR SQLEXCEPTION
Возврат из ф-цииRETURN expr;RETURN expr; (в функциях), SELECT (в inline TVF)RETURN expr;RETURN expr;
Табличная ф-цияRETURNS TABLE (...)RETURNS @t TABLE (...) (multi-statement), RETURNS TABLE AS RETURN (...) (inline)PIPELINED TABLE FUNCTIONRETURNS TABLE (...) (с 8.0)
Проверка объектаIF NOT EXISTS (SELECT FROM pg_tables ...)IF NOT EXISTS (SELECT * FROM sys.objects ...)SELECT COUNT(*) FROM user_tables WHERE ...CREATE TABLE IF NOT EXISTS
LIMIT/OFFSETLIMIT n OFFSET mOFFSET m ROWS FETCH NEXT n ROWS ONLYOFFSET m ROWS FETCH NEXT n ROWS ONLY (с 12c)LIMIT n OFFSET m
JSON-операторы->, -&gt;&gt;, @>JSON_VALUE, JSON_QUERYJSON_VALUE, JSON_TABLE->, -&gt;&gt;, JSON_EXTRACT

🔹 Примечание по переносимости:

  • Избегайте диалект-специфичных конструкций (TOP, LIMIT, ::, [ ]) в библиотечном коде.
  • Используйте ANSI JOIN с ON, а не неявное соединение в WHERE:
SELECT *
FROM orders o
JOIN customers c ON c.id = o.customer_id;
  • Для автоинкремента — GENERATED ALWAYS AS IDENTITY (ANSI SQL:2016).

Ошибки​

СитуацияЧто проверить
Команда не найденаPATH, установка пакета, alias
Permission deniedпользователь, группа, sudo, ACL
Неверная версиясм. "Совместимость", --version

Совместимость​

ОбластьПримечание
Версииактуальные LTS/стабильные релизы SQL
Платформыофициальная матрица поддержки вендора
СтандартыRFC, ISO, спецификация API — см. таблицы выше

В подборках​

Статья входит в тематические подборки и блок "С чего начать?" на главной. Соседние шаги того же маршрута:

Справочники — Справочник по Memcached, Справочник по HTML, Справочник по Cypher, Справочник по CSS, Справочник по Cassandra, Справочник-шпаргалка по Git.