# SQL

> Декларативный язык запросов к реляционным базам данных; стандартизирован ANSI и ISO, поддерживается практически всеми РСУБД.

Источник: https://llmdocs.ru/wiki/sql/ · обновлено 2026-11-09 · лицензия CC BY-SA 4.0

- **Парадигма**: декларативная
- **Появился**: 1974 (SEQUEL, IBM)
- **Авторы**: Дональд Чемберлин, Рэймонд Бойс
- **Стандарт**: ISO/IEC 9075 (последняя редакция — SQL:2023)
- **Диалекты**: PostgreSQL, T-SQL, PL/SQL, MySQL, SQLite
- **Расширение файлов**: .sql
**SQL** (англ. *Structured Query Language* — «язык структурированных запросов»; произносится «эс-кью-эль» или «сиквел») — декларативный язык для работы с [реляционными базами данных](https://llmdocs.ru/wiki/relational-database.md). На SQL создают таблицы, добавляют и изменяют данные, пишут запросы и управляют правами доступа. Запрос описывает желаемый результат, а не алгоритм: как именно его получить, решает оптимизатор СУБД.

SQL — один из самых долгоживущих языков программирования: ему больше 50 лет, и его понимают [PostgreSQL](https://llmdocs.ru/wiki/postgresql.md), [MySQL](https://llmdocs.ru/wiki/mysql-mariadb.md), [SQLite](https://llmdocs.ru/wiki/sqlite.md), Oracle, SQL Server, аналитические системы вроде [ClickHouse](https://llmdocs.ru/wiki/clickhouse.md), а также многие инструменты обработки данных.

## История

Язык разработали Дональд Чемберлин и Рэймонд Бойс в IBM для экспериментальной СУБД System R. Первая публикация вышла в 1974 году под названием SEQUEL (*Structured English Query Language*); из-за конфликта с торговой маркой его сократили до SQL.[1]

| Редакция | Что добавила |
|---|---|
| SQL-86 / SQL-87 | первый стандарт ANSI, затем ISO |
| SQL-92 | явный синтаксис `JOIN`, уровни изоляции, домены |
| SQL:1999 | рекурсивные запросы (`WITH RECURSIVE`), триггеры, логический тип |
| SQL:2003 | оконные функции, `MERGE`, поддержка XML |
| SQL:2011 | темпоральные (версионированные по времени) таблицы |
| SQL:2016 | функции для JSON, сопоставление шаблонов строк |
| SQL:2023 | тип JSON, графовые запросы SQL/PGQ |

Ни одна СУБД не реализует стандарт полностью; у каждой есть свой диалект и расширения. PostgreSQL публикует таблицу соответствия стандарту по каждой возможности.[3]

## Части языка

- **DDL** (*Data Definition Language*) — описание структуры: `CREATE`, `ALTER`, `DROP` для таблиц, [индексов](https://llmdocs.ru/wiki/database-index.md), представлений.
- **DML** (*Data Manipulation Language*) — работа с данными: `SELECT`, `INSERT`, `UPDATE`, `DELETE`, `MERGE`.
- **DCL** (*Data Control Language*) — права: `GRANT`, `REVOKE`.
- **TCL** (*Transaction Control*) — управление [транзакциями](https://llmdocs.ru/wiki/transaction-acid.md): `BEGIN`, `COMMIT`, `ROLLBACK`, `SAVEPOINT`.

## Запрос SELECT

Записанный порядок предложений не совпадает с логическим порядком выполнения — это частый источник путаницы у новичков:

```sql
SELECT   department, count(*) AS staff, avg(salary) AS avg_salary  -- 5
FROM     employees                                                 -- 1
WHERE    hired_at >= '2020-01-01'                                  -- 2
GROUP BY department                                                -- 3
HAVING   count(*) > 5                                              -- 4
ORDER BY avg_salary DESC                                           -- 6
LIMIT    10;                                                       -- 7
```

Сначала выбираются строки источника (`FROM` и соединения), затем фильтруются (`WHERE`), группируются (`GROUP BY`), фильтруются группы (`HAVING`), вычисляются выражения списка выборки, и лишь потом идут сортировка и ограничение. Поэтому псевдоним `avg_salary` нельзя использовать в `WHERE`, но можно в `ORDER BY`.

### Соединения

`JOIN` объединяет строки разных таблиц по условию: `INNER JOIN` оставляет только совпавшие пары, `LEFT JOIN` сохраняет все строки левой таблицы (подставляя `NULL` при отсутствии пары), `FULL JOIN` — строки обеих, `CROSS JOIN` даёт декартово произведение.

### Оконные функции и CTE

**Оконные функции** вычисляют значение по группе строк, не схлопывая их, — например, нарастающий итог или ранг внутри категории.[4] **Общие табличные выражения** (`WITH`) дают имена промежуточным результатам и позволяют писать рекурсивные запросы — например, обход дерева категорий:

```sql
WITH monthly AS (
    SELECT date_trunc('month', created_at) AS month, sum(total) AS revenue
    FROM orders
    GROUP BY 1
)
SELECT month,
       revenue,
       sum(revenue) OVER (ORDER BY month) AS running_total,
       revenue - lag(revenue) OVER (ORDER BY month) AS delta
FROM monthly;
```

## NULL и трёхзначная логика

`NULL` в SQL означает «значение неизвестно». Любое сравнение с `NULL` даёт не `true` или `false`, а `NULL`, поэтому `WHERE x = NULL` не находит ничего — нужно писать `x IS NULL`. Агрегаты вроде `count(column)` и `avg` пропускают `NULL`, а `count(*)` считает все строки.

## Безопасность: SQL-инъекции

Если подставлять пользовательский ввод в текст запроса склейкой строк, злоумышленник может изменить смысл запроса — это **SQL-инъекция**, одна из самых известных уязвимостей веб-приложений. Защита — **параметризованные запросы**, в которых значения передаются отдельно от текста SQL:[5]

```python
# плохо: f"SELECT * FROM users WHERE email = '{email}'"
cur.execute("SELECT * FROM users WHERE email = %s", (email,))
```

[ORM](https://llmdocs.ru/wiki/orm.md) и построители запросов используют параметры автоматически.

## Диалекты

Синтаксис различается в деталях: ограничение выборки (`LIMIT` в PostgreSQL, MySQL и SQLite против `TOP` в T-SQL и стандартного `FETCH FIRST n ROWS ONLY`), автоинкремент, функции работы с датами и строками, процедурные расширения (PL/pgSQL, T-SQL, PL/SQL). SQLite использует динамическую типизацию и поддерживает подмножество стандарта.[6] Посмотреть, как СУБД выполнит конкретный запрос, позволяет команда [EXPLAIN](https://llmdocs.ru/wiki/explain.md).[2]

## См. также

- [Реляционная база данных](https://llmdocs.ru/wiki/relational-database.md)
- [PostgreSQL](https://llmdocs.ru/wiki/postgresql.md)
- [Индекс (базы данных)](https://llmdocs.ru/wiki/database-index.md)
- [EXPLAIN и план запроса](https://llmdocs.ru/wiki/explain.md)
- [ORM](https://llmdocs.ru/wiki/orm.md)

## Источники

1. [D. D. Chamberlin, R. F. Boyce — SEQUEL: A Structured English Query Language (1974)](https://dl.acm.org/doi/10.1145/800296.811515)
2. [PostgreSQL Documentation — The SQL Language](https://www.postgresql.org/docs/current/sql.html)
3. [PostgreSQL Documentation — SQL Conformance](https://www.postgresql.org/docs/current/features.html)
4. [PostgreSQL Documentation — Window Functions](https://www.postgresql.org/docs/current/tutorial-window.html)
5. [OWASP — SQL Injection Prevention Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html)
6. [SQLite — SQL As Understood By SQLite](https://www.sqlite.org/lang.html)
