Функции строк и работа с датами

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

Чему научишься за этот урок:
— приводить текст к одному регистру через LOWER/UPPER;
— убирать лишние пробелы через TRIM;
— соединять строки через CONCAT и узнавать длину строки через LENGTH;
— фильтровать записи за период через сравнение дат и BETWEEN.

Функции строк

LOWER() приводит текст к нижнему регистру, UPPER() — к верхнему. Это полезно, когда тестировщик не уверен, в каком регистре хранятся данные, но хочет найти запись независимо от этого.

SELECT * FROM users WHERE LOWER(email) = LOWER('Ivan@Example.com');
-- сравнение приведёт ОБЕ стороны к нижнему регистру
-- найдёт email независимо от того, как он реально записан в базе:
-- 'ivan@example.com', 'IVAN@EXAMPLE.COM', 'Ivan@Example.com' -- всё совпадёт

TRIM() убирает пробелы по краям строки — в начале и в конце. Это частая причина «глючных» проверок: в данных иногда оказывается незаметный лишний пробел (например, из-за копирования из другого поля), и сравнение строк без TRIM может не сработать, хотя на глаз строки выглядят одинаково.

SELECT * FROM users WHERE TRIM(name) = 'Иван';
-- найдёт 'Иван', даже если в базе реально хранится ' Иван' или 'Иван ' с пробелами по краям

CONCAT() соединяет несколько строк в одну. LENGTH() возвращает длину строки в символах.

SELECT CONCAT(name, ' <', email, '>') FROM users;
-- склеит имя и email в одну строку вида: Иван <ivan@example.com>

SELECT LENGTH(name) FROM users;
-- вернёт число символов в столбце name для каждой строки

Работа с датами

Даты в SQL можно сравнивать обычными операторами сравнения — так же, как числа:

SELECT * FROM users WHERE created_at >= '2026-01-01';
-- все пользователи, зарегистрированные 1 января 2026 или позже

Для этой темы в enrollments есть столбец enrolled_at — дата И время записи на курс (тип TIMESTAMP). Для диапазона «от и до» в SQL есть BETWEEN: он проверяет, что значение попадает в диапазон, обе границы включаются. Но у столбца с датой и временем здесь ловушка: дата без времени означает полночь, начало этого дня.

SELECT * FROM enrollments WHERE enrolled_at BETWEEN '2026-01-01' AND '2026-01-31';
-- ловушка: '2026-01-31' = 31 января 00:00:00
-- запись '2026-01-31 19:30' в результат НЕ попадёт

SELECT * FROM enrollments
WHERE enrolled_at >= '2026-01-01' AND enrolled_at < '2026-02-01';
-- правильно: весь январь, включая 31 января до конца дня
-- верхняя граница — начало СЛЕДУЮЩЕГО месяца, знак строго меньше

BETWEEN хорош, когда в столбце только дата без времени (тип DATE). Если в столбце есть время, надёжнее писать диапазон так: >= начало периода и < начало следующего периода. Так в результат попадает весь последний день и не попадает ни одной лишней секунды.

Важно: точный синтаксис функций для работы с датами МОЖЕТ отличаться между разными СУБД (система управления базами данных, например PostgreSQL и MySQL) — они по-разному называют некоторые функции извлечения месяца или года. Этот урок даёт общее понимание идеи — сравнение и диапазон дат, — а не точный синтаксис конкретной базы. На реальном проекте точный синтаксис нужной СУБД всегда стоит сверять с её документацией.

Итог:
— LOWER()/UPPER() приводят текст к одному регистру для сравнения без учёта регистра;
— TRIM() убирает пробелы по краям строки — частая причина ложных несовпадений;
— CONCAT() соединяет строки, LENGTH() возвращает длину строки;
— даты сравниваются обычными операторами, BETWEEN задаёт диапазон «от и до» и включает обе границы; для даты со временем диапазон пишут как >= начало AND < начало следующего периода;
— точный синтаксис функций дат зависит от конкретной СУБД, курс даёт только общую идею.

Контрольный вопрос. Зачем нужна функция LOWER() при сравнении строк?

АЧтобы сравнить текст независимо от регистра
БЧтобы убрать лишние пробелы по краям строки
ВЧтобы соединить несколько строк текста в одну

Подсказка: В уроке есть прямой пример с email, где регистр букв может отличаться.

Онлайн-проверка ответа появится позже

Контрольный вопрос. Что делает функция TRIM()?

АУбирает пробелы по краям строки — в начале и в конце
БПриводит текст к верхнему регистру
ВВозвращает количество символов в строке

Подсказка: В уроке эта функция названа частой причиной ‘глючных’ проверок из-за незаметных пробелов.

Онлайн-проверка ответа появится позже

Контрольный вопрос. Какой оператор удобно использовать, чтобы отфильтровать записи в диапазоне дат «от и до»?

АORDER BY
БBETWEEN
ВGROUP BY

Подсказка: В уроке этот оператор разобран в разделе про работу с датами, сразу после сравнения через >=.

Онлайн-проверка ответа появится позже

Контрольный вопрос. Что возвращает функция LENGTH(name)?

АЧисло символов в значении столбца name
БСписок всех уникальных имён в таблице
ВПервую букву значения столбца name

Подсказка: В уроке LENGTH() разобрана в одной группе с CONCAT() — про строки, а не про сами данные.

Онлайн-проверка ответа появится позже

Контрольный вопрос. Столбец enrolled_at хранит дату и время. Дан запрос: SELECT * FROM enrollments WHERE enrolled_at BETWEEN ‘2026-01-01’ AND ‘2026-01-31’; Какие из утверждений про него верны (выбери все подходящие)?

Выберите все верные варианты.

АЗапись, сделанная 31 января 2026 в 19:30, в результат не попадёт
БЗапись, сделанная ровно 1 января 2026 в 00:00, в результат попадёт — границы BETWEEN включаются
ВЕсли поменять границы местами — BETWEEN ‘2026-01-31’ AND ‘2026-01-01’ — результат будет тем же
ГЗапрос сработает одинаково в любой СУБД без каких-либо отличий в синтаксисе
ДBETWEEN работает только с датами, для чисел и текста его применять нельзя
ЕЧтобы взять весь январь, надёжнее написать enrolled_at >= ‘2026-01-01’ AND enrolled_at < '2026-02-01'

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

Онлайн-проверка ответа появится позже

Контрольный вопрос. Какая функция соединяет несколько строк в одну? Ответь одним словом по-английски, как в уроке.

Подсказка: Она разобрана рядом с LENGTH() в разделе про функции строк.

Онлайн-проверка ответа появится позже

Задание. В таблице users значение email хранится то с заглавными, то со строчными буквами. В уроке для такого сравнения используется одна конкретная SQL-функция приведения строки к нижнему регистру, которую подставляют вокруг обеих сравниваемых величин в WHERE. Как она называется? Ответь одним словом по-английски.

Подсказка: В уроке разобран именно такой пример с email.

✅ Готово, если: ты ввёл(а) верный ответ, и онлайн-проверка его приняла.

Онлайн-проверка ответа появится позже

Задание. Тестировщик сравнивает name = ‘Мария’, но проверка не находит запись, хотя на глаз в таблице точно есть строка ‘Мария’. Похоже, в данных случайно оказался лишний пробел по краю строки. Какую функцию нужно применить к столбцу name, чтобы проверка сработала? Ответь одним словом по-английски.

Подсказка: Это ровно тот сценарий, который в уроке назван частой причиной ‘глючных’ проверок.

✅ Готово, если: ты ввёл(а) верный ответ, и онлайн-проверка его приняла.

Онлайн-проверка ответа появится позже

Задание. Дан фрагмент таблицы enrollments (столбцы id, user_id, course_id, enrolled_at; enrolled_at хранит дату и время):
id=1, enrolled_at=’2026-02-03 10:15′
id=2, enrolled_at=’2026-01-15 09:00′
id=3, enrolled_at=’2026-03-01 00:00′
id=4, enrolled_at=’2026-02-28 18:40′
Напиши SQL-запрос, который вернёт все записи, сделанные в феврале 2026 года (включая записи 28 февраля в любое время дня), и укажи, какие id попадут в результат.

Подсказка: Подумай, какой момент означает дата ‘2026-02-28’ без времени — попадёт ли тогда запись id=4? Верхнюю границу удобнее взять началом следующего месяца.

✅ Готово, если: программа запускается без ошибок и выводит то, что просят в задании.

Онлайн-проверка ответа появится позже

Задание. Тестировщик проверяет форму регистрации: подозревает баг, из-за которого email иногда сохраняется с лишним пробелом в конце и не всегда в одном регистре (например, вместо ‘ivan@example.com’ в базе может оказаться ‘Ivan@Example.com ‘ с пробелом). Напиши один SQL-запрос к таблице users, который найдёт пользователя с email ‘ivan@example.com’ НЕЗАВИСИМО от регистра и лишних пробелов по краям, объединив нужные функции строк, и объясни в 1-2 предложениях, почему нужны обе функции сразу, а не одна.

Подсказка: Функции можно вкладывать друг в друга: сначала одна обрабатывает строку, затем результат обрабатывает вторая.

✅ Готово, если: программа запускается без ошибок и выводит то, что просят в задании.

Онлайн-проверка ответа появится позже

Что дальше

Теперь вы умеете чистить и фильтровать данные по строкам и датам. Дальше — новые приёмы работы с данными.

← Назад  ·  ↑ В начало урока  ·  ⌂ В начало курса  ·  Вперёд →

Школа Виктора Комлева