Выбирать, фильтровать, искать по шаблону, сортировать и ограничивать строки — это основа. Но не всегда данные в базе идеально чистые: буквы бывают то заглавные, то строчные, в тексте случайно оказываются лишние пробелы, а даты нужно уметь сравнивать и фильтровать за конкретный период. Для этого в 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()?
Подсказка: В уроке эта функция названа частой причиной ‘глючных’ проверок из-за незаметных пробелов.
Онлайн-проверка ответа появится позже
Контрольный вопрос. Какой оператор удобно использовать, чтобы отфильтровать записи в диапазоне дат «от и до»?
Подсказка: В уроке этот оператор разобран в разделе про работу с датами, сразу после сравнения через >=.
Онлайн-проверка ответа появится позже
Контрольный вопрос. Что возвращает функция LENGTH(name)?
Подсказка: В уроке LENGTH() разобрана в одной группе с CONCAT() — про строки, а не про сами данные.
Онлайн-проверка ответа появится позже
Контрольный вопрос. Столбец enrolled_at хранит дату и время. Дан запрос: SELECT * FROM enrollments WHERE enrolled_at BETWEEN ‘2026-01-01’ AND ‘2026-01-31’; Какие из утверждений про него верны (выбери все подходящие)?
Выберите все верные варианты.
Подсказка: Помни: дата без времени в сравнении означает полночь, начало этого дня. И проверь, какие утверждения противоречат замечанию урока про разные СУБД.
Онлайн-проверка ответа появится позже
Контрольный вопрос. Какая функция соединяет несколько строк в одну? Ответь одним словом по-английски, как в уроке.
Подсказка: Она разобрана рядом с 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 предложениях, почему нужны обе функции сразу, а не одна.
Подсказка: Функции можно вкладывать друг в друга: сначала одна обрабатывает строку, затем результат обрабатывает вторая.
✅ Готово, если: программа запускается без ошибок и выводит то, что просят в задании.
Онлайн-проверка ответа появится позже
Что дальше
Теперь вы умеете чистить и фильтровать данные по строкам и датам. Дальше — новые приёмы работы с данными.
