LOWER: примеры (SQL)
LOWER(character_expression): stringОписание функции LOWER в MS SQL Server
Функция LOWER входит в состав строковых функций Microsoft SQL Server. Ее основное назначение — преобразование всех символов заданной строки в нижний регистр. Эта операция часто называется case-insensitive преобразованием или приведением к нижнему регистру.
Функция применяется в ситуациях, когда необходимо стандартизировать текстовые данные для сравнения или агрегации без учета регистра символов. Типичные примеры использования включают нормализацию данных перед вставкой, сравнение логинов или email-адресов, где регистр не имеет значения, а также подготовку данных для отчетов.
Синтаксис функции крайне прост: LOWER ( character_expression ).
- character_expression: Единственный входной аргумент. Это выражение символьного или двоичного типа данных, которое может быть константой, переменной или столбцом. Типы данных:
char,varchar,text,nchar,nvarchar,ntext. Аргумент неявно преобразуется в типvarchar, если он имеет другой символьный тип, за исключениемtext,ntextиimage.
Возвращаемое значение всегда соответствует типу входного аргумента, за исключением случаев с типами text/ntext, где возвращается varchar(max)/nvarchar(max). Если аргумент имеет значение NULL, функция также возвращает NULL.
Простые примеры использования LOWER
Ниже представлены базовые варианты применения функции с различными типами входных данных.
Пример 1: Преобразование строковой константы.
SELECT LOWER('SQL Server - RDBMS') AS Result;Result --------------- sql server - rdbms
Пример 2: Использование с данными из столбца таблицы.
SELECT LastName, LOWER(LastName) AS LowerName
FROM Employees
WHERE EmployeeID = 1;
-- Предположим, LastName = 'Иванов'LastName LowerName -------- ---------- Иванов иванов
Пример 3: Работа с Unicode данными (NCHAR, NVARCHAR).
SELECT LOWER(N'ПРИВЕТ МИР') AS Result;Result ----------- привет мир
Пример 4: Функция не изменяет символы, уже находящиеся в нижнем регистре, или не-буквенные символы.
SELECT LOWER('Test123!@# Test') AS Result;Result -------------- test123!@# test
Похожие строковые функции в MS SQL
В T-SQL существуют и другие функции для работы с регистром символов:
- UPPER(character_expression): Выполняет обратное преобразование — переводит все символы строки в верхний регистр. Используется аналогично LOWER.
- COLLATE: Предложение для задания параметров сортировки на уровне выражения, запроса или базы данных. Позволяет выполнять сравнения без учета регистра, не изменяя сами данные. Например, сравнение
WHERE Name COLLATE SQL_Latin1_General_CP1_CI_AS = 'test'будет игнорировать регистр для столбца Name.
Выбор между LOWER/UPPER и COLLATE: Функции LOWER/UPPER физически изменяют данные, что может повлиять на производительность при обработке больших объемов или использовании в условиях JOIN и WHERE, так как индексы по исходному столбцу могут не использоваться. Предложение COLLATE часто предпочтительнее для сравнений, так как оно лишь задает правила сравнения на лету, не меняя значения. Однако для стандартизации хранимых данных или подготовки их для внешних систем все же применяют LOWER/UPPER.
Аналоги функции в других СУБД и языках
Концепция приведения строки к нижнему регистру поддерживается практически во всех современных СУБД, хотя имена функций или их поведение могут незначительно отличаться.
MySQL: Функция также называется LOWER(). Существует синоним LCASE(). Работает аналогично SQL Server.
SELECT LOWER('MySQL'), LCASE('MySQL');LOWER('MySQL') | LCASE('MySQL')
---------------|----------------
mysql | mysqlOracle: Основная функция — LOWER(). Также есть функция NLSLOWER() для учета параметров языкового окружения (NLS).
SELECT LOWER('Oracle DB') FROM dual;LOWER('ORACLEDB')
----------------
oracle dbPostgreSQL: Используется функция LOWER(). Работает одинаково для всех символьных типов.
SELECT LOWER('PostgreSQL');lower ---------- postgresql
SQLite: Поддерживается функция LOWER(), но ее работа зависит от настроенной сборки и регистрозависимости может не распространяться на символы за пределами ASCII без соответствующих расширений.
SELECT LOWER('SQLite');lower('SQLite')
---------------
sqliteОсновное отличие между реализациями часто заключается в поддержке локалей и правил преобразования для специфических алфавитов (например, турецкого с точками и без точек над 'i'). В SQL Server это регулируется параметрами сортировки (Collation) сервера или базы данных.
Типичные ошибки и особенности
Использование функции LOWER обычно не вызывает сложностей, но есть несколько моментов, на которые стоит обратить внимание.
1. Ожидание преобразования не-буквенных символов. Функция не влияет на цифры, знаки препинания и специальные символы.
-- Ожидание, что '!' станет другим символом — ошибочно.
SELECT LOWER('TEST!') AS Result;Result ------ test!
2. Работа с NULL. Если входное значение NULL, результатом также будет NULL, что может привести к неожиданным результатам в конкатенации.
SELECT LOWER(NULL) AS Result, 'Prefix' + LOWER(NULL) AS Concatenated;Result | Concatenated -------|------------- NULL | NULL
3. Невосприимчивость к уже измененному регистру. Многократное применение функции избыточно, но не вызывает ошибки.
SELECT LOWER(LOWER('HELLO')) AS Result; -- Второй вызов бесполезенResult ------ hello
4. Потеря производительности в условиях WHERE. Использование LOWER в левой части условия сравнения делает выражение недетерминированным и может препятствовать использованию индекса по столбцу.
-- Медленный запрос (если на Name есть индекс, он может не использоваться):
SELECT * FROM Users WHERE LOWER(Name) = 'иван';
-- Более оптимальный вариант (если сортировка CI):
SELECT * FROM Users WHERE Name = 'иван' COLLATE SQL_Latin1_General_CP1_CI_AS;Изменения в последних версиях MS SQL Server
Функция LOWER является одной из базовых строковых функций и ее ядро не претерпевало существенных изменений в последних основных версиях SQL Server (2012, 2014, 2016, 2017, 2019, 2022).
Основные эволюционные изменения связаны не с самой функцией, а с контекстом ее использования:
- Поддержка UTF-8: Начиная с SQL Server 2019, появилась поддержка кодировки UTF-8 для типов данных
CHARиVARCHARпри использовании соответствующих параметров сортировки (например,Latin1_General_100_CI_AS_SC_UTF8). Функция LOWER корректно обрабатывает символы в этой кодировке, расширяя свой диапазон действия по сравнению со старыми однобайтовыми кодировками. - Улучшение производительности: Общие оптимизации обработчика запросов в новых версиях могут косвенно влиять на скорость выполнения операций с функциями, в том числе с LOWER, особенно в сочетании с другими строковыми преобразованиями.
Таким образом, синтаксис и базовое поведение функции остаются стабильными и обратно совместимыми.
Расширенные и специализированные примеры
Функция LOWER может быть частью более сложных выражений и сценариев.
Пример 1: Стандартизация данных при вставке (триггер).
CREATE TRIGGER trg_StandardizeEmail
ON Users
AFTER INSERT, UPDATE
AS
BEGIN
UPDATE u
SET u.Email = LOWER(i.Email)
FROM Users u
INNER JOIN inserted i ON u.UserID = i.UserID
WHERE u.Email <> LOWER(i.Email) -- Избегаем бесконечных обновлений
END;Пример 2: Поиск без учета регистра в столбце с регистрозависимой сортировкой (CS).
-- Если столбец Name имеет collation с суффиксом _CS
DECLARE @SearchName NVARCHAR(100) = N'иванов';
SELECT *
FROM Customers
WHERE LOWER(Name) = LOWER(@SearchName);
-- Альтернатива с COLLATE
SELECT *
FROM Customers
WHERE Name COLLATE SQL_Latin1_General_CP1_CI_AS = @SearchName;Пример 3: Группировка данных без учета регистра.
SELECT LOWER(ProductName) AS StandardName,
COUNT(*) AS ProductCount,
STRING_AGG(ProductName, ', ') WITHIN GROUP (ORDER BY ProductName) AS OriginalNames
FROM Products
GROUP BY LOWER(ProductName)
HAVING COUNT(*) > 1; -- Поиск потенциальных дубликатов в названияхStandardName | ProductCount | OriginalNames -------------|--------------|----------------- soda | 2 | Soda, SODA
Пример 4: Использование в CHECK-ограничении для обеспечения данных в нижнем регистре.
ALTER TABLE Users
ADD CONSTRAINT CHK_Email_Lowercase
CHECK (Email = LOWER(Email));
-- При попытке вставить 'USER@DOMAIN.COM' ограничение вызовет ошибку.Пример 5: Комбинация с другими строковыми функциями.
-- Очистка и стандартизация строки
SELECT LOWER(LTRIM(RTRIM(' HELLO World '))) AS CleanedString;
-- Результат: 'hello world'-- Извлечение домена из email в нижнем регистре
SELECT Email,
LOWER(SUBSTRING(Email, CHARINDEX('@', Email) + 1, LEN(Email))) AS DomainLower
FROM Users;