Литералы, выражения и вычисляемые колонки

Литералы, выражения и вычисляемые колонки

До этого момента в SELECT-списке мы писали только имена колонок. Но SQL позволяет значительно больше: вычислять арифметические выражения, строить строки, подставлять константы и даже комбинировать всё это прямо в запросе. В этом уроке разберём литералы — «жёсткие» значения прямо в коде, и выражения — вычисления над данными из таблицы.

Что такое литерал

Литерал — это фиксированное значение, записанное непосредственно в запросе. Он не берётся из таблицы; он всегда возвращает одно и то же.

Примеры литералов разных типов:

SELECT 42;               -- числовой литерал
SELECT 3.14;             -- дробный литерал
SELECT 'Привет, мир';   -- строковый литерал (в одинарных кавычках)
SELECT TRUE;             -- логический литерал
SELECT NULL;             -- специальное значение «ничего»

Строковые литералы всегда в одинарных кавычках. Двойные кавычки в SQL — для имён объектов (таблиц, колонок). Путать их — типичная ошибка.

Литералы можно добавлять как «колонки» в SELECT:

SELECT name, 'активен' AS статус
FROM   employees;

Результат: для каждой строки в колонке статус будет стоять строка 'активен'. Это может показаться бесполезным, но иногда нужно добавить константу к результату — например, метку источника данных или фиксированное значение по умолчанию.

Арифметические выражения

В SELECT-списке можно использовать арифметику над числовыми колонками. Все базовые операторы работают стандартно:

ОператорСмыслПример
+сложениеprice + 100
-вычитаниеprice - discount
*умножениеprice * quantity
/делениеtotal / count
%остаток от деленияid % 2

Пример — таблица order_items (позиции заказа):

SELECT product_name,
       quantity,
       unit_price,
       quantity * unit_price AS total_price
FROM   order_items;

Результат:

product_name | quantity | unit_price | total_price
-------------+----------+------------+------------
Ноутбук      | 2        | 55000      | 110000
Мышь         | 5        | 1200       | 6000
Монитор      | 1        | 28000      | 28000

Колонка total_price — вычисляемая. Её нет в таблице; СУБД считает её на лету для каждой строки. Псевдоним AS total_price даёт ей понятное имя.

Проверь себя: что вернёт выражение price * 1.2 AS price_with_vat для price = 1000?

Целочисленное деление и дроби

Важная деталь: в PostgreSQL деление целых чисел даёт целое число. Остаток отбрасывается:

SELECT 7 / 2;    -- результат: 3, не 3.5
SELECT 7.0 / 2;  -- результат: 3.5

Если нужен дробный результат, хотя бы один из операндов должен быть дробным числом. Часто используют явное приведение типа:

SELECT total::DECIMAL / count AS average
FROM   statistics;

:: — оператор приведения типа в PostgreSQL. DECIMAL означает дробное число. Детали типов данных будем разбирать подробнее в модуле 9.

Строковые выражения: конкатенация

Строки в SQL объединяются оператором || (двойная вертикальная черта):

SELECT first_name || ' ' || last_name AS full_name
FROM   employees;

Результат:

full_name
-----------
Анна Иванова
Борис Петров
Вера Сидорова

Оператор || берёт строки и «склеивает» их. В примере выше между именем и фамилией добавлена строка ' ' (пробел) — иначе имена бы слиплись: АннаИванова.

PostgreSQL также предоставляет функцию CONCAT(), которая делает то же самое, но чуть иначе обрабатывает NULL:

SELECT CONCAT(first_name, ' ', last_name) AS full_name
FROM   employees;

CONCAT() игнорирует NULL-аргументы; || вернёт NULL, если любой из операндов — NULL. Это важная разница, которую стоит держать в голове.

Проверь себя: что вернёт 'Иван' || NULL || 'ов' в PostgreSQL?

Функции в выражениях

SQL поддерживает множество встроенных функций, которые можно использовать прямо в SELECT. Несколько полезных примеров:

SELECT name,
       UPPER(name)  AS name_upper,  -- все буквы заглавные
       LOWER(name)  AS name_lower,  -- все буквы строчные
       LENGTH(name) AS name_length  -- длина строки
FROM   products;

Функции для чисел:

SELECT price,
       ROUND(price * 0.13, 2) AS tax,   -- округление до 2 знаков
       ABS(balance)           AS abs_balance  -- модуль числа
FROM   finance;

Функции работают так же, как в любом языке программирования: принимают аргументы, возвращают результат. Полный список встроенных функций PostgreSQL огромен — заглядывайте в документацию по мере необходимости.

Выражения с датами

С датами тоже можно делать вычисления. PostgreSQL поддерживает арифметику над датами:

SELECT name,
       hire_date,
       CURRENT_DATE - hire_date AS days_employed
FROM   employees;

CURRENT_DATE — встроенная функция, возвращающая сегодняшнюю дату. Разность двух дат даёт количество дней. Работа с датами — обширная тема, которая будет в разделе типов данных.

Выражения без таблицы

Как мы уже видели в уроке про синтаксис SELECT, PostgreSQL позволяет использовать SELECT без FROM:

SELECT 10 + 5;           -- 15
SELECT 'SQL' || ' OK';   -- SQL OK
SELECT UPPER('hello');   -- HELLO
SELECT CURRENT_DATE;     -- сегодняшняя дата

Это удобно для быстрой проверки выражений в консоли — своего рода «калькулятор» прямо в psql.

Приоритет операторов

Арифметические операторы следуют стандартным математическим правилам приоритета: * и / выполняются до + и -. Скобки меняют порядок:

SELECT price + discount * 2;    -- discount * 2, затем + price
SELECT (price + discount) * 2;  -- сначала сложение, потом умножение

Когда не уверены в приоритете — ставьте скобки. Явность лучше неожиданного результата.

Типичные ошибки с литералами

1. Двойные кавычки вместо одинарных для строк:

SELECT "Привет" AS message;  -- ошибка: PostgreSQL ищет колонку с именем "Привет"
SELECT 'Привет' AS message;  -- правильно: строковый литерал

2. Деление целых чисел:

SELECT 1 / 3;    -- результат: 0, не 0.333...
SELECT 1.0 / 3;  -- результат: 0.3333...

3. NULL в арифметике:

SELECT 5 + NULL;  -- результат: NULL
SELECT 5 * NULL;  -- результат: NULL

Любая арифметическая операция с NULL возвращает NULL. Это «вирусное» поведение NULL — одна из особенностей SQL, которую важно знать.

Практический пример: прайс-лист с расчётами

Соберём всё вместе:

SELECT name                        AS "Товар",
       price                       AS "Цена",
       price * 0.9                 AS "Цена со скидкой 10%",
       ROUND(price * 0.13, 2)      AS "НДС",
       'руб.'                      AS "Валюта"
FROM   products;

Этот запрос возвращает таблицу с пятью колонками — три вычислены на лету, одна взята из таблицы, одна — константа. Всё это без изменения исходных данных.

Когда выражения особенно полезны

Вот несколько реальных сценариев, где вычисляемые колонки незаменимы:

Отчёты и аналитика. Вместо того чтобы вытягивать «сырые» данные и считать в Python или Excel, можно вычислить прямо в SQL:

SELECT year,
       revenue,
       costs,
       revenue - costs          AS profit,
       (revenue - costs) * 100.0 / revenue AS profit_margin_percent
FROM   annual_stats;

Форматирование данных. Собрать полное имя из частей, добавить единицы измерения:

SELECT last_name || ', ' || first_name AS "ФИО",
       salary || ' руб.'               AS "Зарплата"
FROM   employees;

Нормализация значений. Перевести единицы на лету:

SELECT product_name,
       weight_grams                    AS "Вес (г)",
       weight_grams / 1000.0           AS "Вес (кг)"
FROM   products;

Все эти вычисления выполняются на стороне сервера БД, без загрузки данных в приложение. Это эффективно и удобно.

Выражения и DISTINCT

Вычисляемые колонки хорошо работают вместе с DISTINCT, который вы изучили в предыдущем уроке:

SELECT DISTINCT UPPER(category) AS category_upper
FROM   products;

Сначала для каждой строки применяется функция UPPER(), затем DISTINCT убирает дубликаты. Порядок логический: сначала вычисления, потом дедупликация.

Краткий итог

  • Литерал — фиксированное значение прямо в запросе: числа, строки в 'кавычках', TRUE/FALSE, NULL
  • Арифметика: +, -, *, /, %; деление целых даёт целое
  • Конкатенация строк: ||; CONCAT() — альтернатива с другим поведением для NULL
  • Встроенные функции (UPPER, LENGTH, ROUND) работают прямо в SELECT
  • Любая операция с NULL возвращает NULL
  • Строковые литералы — одинарные кавычки; двойные — для имён объектов

Что дальше

Вы освоили вычисления прямо в SELECT. Финальный урок этого модуля посвящён оформлению запросов: комментарии, форматирование, читаемость кода. Это не «синтаксис», но хорошие привычки с самого начала сэкономят много времени.

Попробуйте интерактивную версию

Практические задачи, квизы и AI-наставник — бесплатный старт без карты

Перейти к практике