В прошлом уроке мы научились выбирать, фильтровать, искать по шаблону, сортировать и ограничивать данные. Но не всегда данные в базе идеально чистые: буквы бывают то заглавные, то строчные, в тексте случайно оказываются лишние пробелы, а даты нужно уметь сравнивать и фильтровать за конкретный период. Для этого в 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 (дата и время записи на курс). Когда нужен диапазон дат — «от и до», — удобнее использовать BETWEEN: он проверяет, что значение попадает в указанный диапазон (границы включаются).
SELECT * FROM enrollments WHERE enrolled_at BETWEEN '2026-01-01' AND '2026-01-31'; -- все записи на курсы, сделанные в течение января 2026 года
Важно: точный синтаксис функций для работы с датами МОЖЕТ отличаться между разными СУБД (система управления базами данных, например PostgreSQL и MySQL) — они по-разному называют некоторые функции извлечения месяца или года. Этот урок даёт общее понимание идеи — сравнение и диапазон дат, — а не точный синтаксис конкретной базы. На реальном проекте точный синтаксис нужной СУБД всегда стоит сверять с её документацией.
Итог:
— LOWER()/UPPER() приводят текст к одному регистру для сравнения без учёта регистра;
— TRIM() убирает пробелы по краям строки — частая причина ложных несовпадений;
— CONCAT() соединяет строки, LENGTH() возвращает длину строки;
— даты сравниваются обычными операторами, BETWEEN задаёт диапазон «от и до»;
— точный синтаксис функций дат зависит от конкретной СУБД, курс даёт только общую идею.
Контрольный вопрос. Зачем нужна функция LOWER() при сравнении строк?
Подсказка: В уроке есть прямой пример с email, где регистр букв может отличаться.
Проверить ответ →
Реальная проверка — на нашей платформе, бесплатно и без регистрации. Открыть задачу и ввести ответ →
Контрольный вопрос. Что делает функция TRIM()?
Подсказка: В уроке эта функция названа частой причиной ‘глючных’ проверок из-за незаметных пробелов.
Проверить ответ →
Реальная проверка — на нашей платформе, бесплатно и без регистрации. Открыть задачу и ввести ответ →
Контрольный вопрос. Какой оператор удобно использовать, чтобы отфильтровать записи в диапазоне дат «от и до»?
Подсказка: В уроке этот оператор разобран в разделе про работу с датами, сразу после сравнения через >=.
Проверить ответ →
Реальная проверка — на нашей платформе, бесплатно и без регистрации. Открыть задачу и ввести ответ →
Контрольный вопрос. Что возвращает функция LENGTH(name)?
Подсказка: В уроке LENGTH() разобрана в одной группе с CONCAT() — про строки, а не про сами данные.
Проверить ответ →
Реальная проверка — на нашей платформе, бесплатно и без регистрации. Открыть задачу и ввести ответ →
Контрольный вопрос. Дан запрос: 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):
id=1, enrolled_at=’2026-02-03′
id=2, enrolled_at=’2026-01-15′
id=3, enrolled_at=’2026-03-01′
id=4, enrolled_at=’2026-02-28′
Напиши SQL-запрос, который вернёт только записи, сделанные в феврале 2026 года (с 1 по 28 число включительно), и укажи, какие id должны попасть в результат.Критерий приёмки: запрос вида SELECT * FROM enrollments WHERE enrolled_at BETWEEN ‘2026-02-01’ AND ‘2026-02-28’; (BETWEEN с границами месяца); названы id=1 и id=4 как единственные записи, попадающие в диапазон.
Подсказка: Определи границы февраля как две даты и используй BETWEEN между ними — так же, как в примере урока с январём.
✅ Готово, если: ответ раскрывает то, что просит критерий приёмки в задании выше.
Онлайн-проверка ответа появится позже
Задание. Тестировщик проверяет форму регистрации: подозревает баг, из-за которого email иногда сохраняется с лишним пробелом в конце и не всегда в одном регистре (например, вместо ‘ivan@example.com’ в базе может оказаться ‘Ivan@Example.com ‘ с пробелом). Напиши один SQL-запрос к таблице users, который найдёт пользователя с email ‘ivan@example.com’ НЕЗАВИСИМО от регистра и лишних пробелов по краям, объединив нужные функции строк, и объясни в 1-2 предложениях, почему нужны обе функции сразу, а не одна.
Критерий приёмки: запрос вида SELECT * FROM users WHERE TRIM(LOWER(email)) = ‘ivan@example.com’; (или LOWER(TRIM(email)) — обе функции вложены друг в друга, обе применены к email); объяснено, что одной функции недостаточно, потому что задачи разные — LOWER решает только регистр, TRIM решает только пробелы, а баг может проявиться в обоих видах одновременно.
Подсказка: Функции можно вкладывать друг в друга: сначала одна обрабатывает строку, затем результат обрабатывает вторая.
✅ Готово, если: ответ раскрывает то, что просит критерий приёмки в задании выше.
Онлайн-проверка ответа появится позже
Что дальше
Теперь вы умеете чистить и фильтровать данные по строкам и датам. В следующем уроке разберём JOIN — как собирать данные сразу из нескольких связанных таблиц и в чём разница между видами JOIN.
