Часть 5 из 16
После WHERE мы умеем находить подходящие события, но пока показываем только то, что уже записано в таблицах. В этой части научимся выводить новые значения прямо в результате запроса: посчитаем длительность концерта, переведём машинный статус в понятную подпись и обсудим точный тип для цены билета.
Это поможет отделить факты, которые нужно хранить, от значений, которые проще вычислять каждый раз. В конце проверим, как формат времени и часовой пояс влияют на расписание.
Считаем длительность
SELECT name,
TIMESTAMPDIFF(MINUTE,starts_at,ends_at) AS duration_minutes,
CASE status
WHEN 'planned' THEN 'Готовится'
WHEN 'open' THEN 'Билеты продаются'
WHEN 'finished' THEN 'Завершено'
ELSE 'Проверьте статус'
END AS status_label
FROM events;
CASE похож на цепочку условий. Алиас после AS задаёт заголовок вычисляемого столбца.
Поиск по названию
SELECT name FROM events WHERE name LIKE '%ночная%';
Процент означает любое число символов. Начальный процент часто мешает обычному индексу текста, но для небольшой таблицы это не проблема.
Деньги и точность
Стоимость билета будем хранить как DECIMAL(8,2): точное десятичное значение с двумя знаками. FLOAT приближённый и способен давать мелкие ошибки округления.
Время означает локальную зону
DATETIME не хранит часовой пояс. Для одного фестиваля договоримся о местном времени площадки; для международной системы нужно единое правило хранения и преобразования зон. Следующая часть свяжет артистов с событиями через JOIN.
Когда вычислять, а когда сохранять?
Поле duration_minutes зависит от двух других значений: времени начала и окончания. Обычно его не нужно хранить отдельно — иначе после переноса времени длительность может устареть. Вычисляемый столбец в SELECT всегда отражает текущие значения. Сохранять результат отдельно имеет смысл лишь при понятной причине и механизме обновления.
Денежный тип DECIMAL(8,2) означает до восьми цифр всего, включая две после точки. Например, 1234.50 помещается; дробная копейка будет округляться согласно правилам преобразования. В отличие от FLOAT, десятичное значение хранится точно в заданном масштабе, поэтому сумма билетов подходит для DECIMAL.
Попробуйте добавить в SELECT вычисление длительности и CASE-подпись статуса. Сравните их с исходными колонками во вкладке результата: строки таблицы не изменятся, потому что запрос только читает данные. Следом добавим артистов, и вычисления впервые появятся в совместном расписании.
Понимаем точность DECIMAL
В записи DECIMAL(8,2) первое число задаёт максимальное количество цифр всего, второе — сколько цифр будет после десятичной точки. Например, 123456.78 использует все восемь цифр, а более крупная сумма уже не поместится без ошибки или преобразования.
Выбирайте диапазон по реальной верхней границе, а не бесконечно увеличивайте его «на всякий случай».
В SQL десятичный разделитель — точка, даже если phpMyAdmin или ваша локаль показывают запятую в интерфейсе. Для цены пишите 1200.50. Не храните денежную стоимость текстом: тогда сортировка может поставить «900» выше «1200», а сложение потребует преобразований.
Решите, где хранить длительность
Если длительность всегда равна разнице начала и конца, вычисляйте её запросом с TIMESTAMPDIFF, как в примере выше. Если сохранить отдельное поле и забыть обновить его после переноса выступления, база будет содержать две противоречащие друг другу истины.
В следующем уроке соединим таблицы и увидим, как вычисляемые колонки работают рядом с данными из связанных сущностей.
Выбираем хранение и вычисление
| Задача | Подход | Почему |
|---|---|---|
| Хранить цену | DECIMAL(8,2) | Точная десятичная стоимость |
| Получать длительность | TIMESTAMPDIFF в SELECT | Не дублируем вычисляемое значение |
| Показывать текст статуса | CASE в SELECT | Исходный статус остаётся машинным |
Если значение можно однозначно получить из уже сохранённых данных, сначала спросите себя, нужно ли хранить его ещё раз.
← Предыдущая статья: WHERE и даты MySQL: находим нужные события
Следующая статья: JOIN в MySQL: связываем артистов, события и площадки →
0
18