
В SQL для работы с подстроками используются функции SUBSTRING, LEFT, RIGHT и CHARINDEX. SUBSTRING позволяет извлечь последовательность символов с заданной позиции и длиной, что особенно полезно при разборе кода товара, номеров заказов или дат в формате строки.
Функция CHARINDEX определяет позицию конкретного символа или подстроки, что дает возможность динамически выделять фрагменты текста. Например, при необходимости извлечь имя пользователя до символа ‘@’ в адресе электронной почты, комбинация SUBSTRING и CHARINDEX позволяет сделать это без создания дополнительных вычисляемых столбцов.
LEFT и RIGHT работают с фиксированными длинами, извлекая символы с начала или конца строки. Эти функции оптимальны для обработки кодов, идентификаторов и стандартных форматов данных, где длина частей заранее известна.
При работе с SQL важно учитывать, что длина строки и позиции символов учитываются в байтах для многобайтовых кодировок, таких как UTF-8. Ошибки в расчетах могут привести к усечению данных. Рекомендуется тестировать функции на примерах, имитирующих реальные данные, и использовать CAST или CONVERT при необходимости приведения типов.
Использование функции SUBSTRING для извлечения подстроки
Функция SUBSTRING позволяет извлечь часть строки по указанной позиции и длине. Синтаксис в большинстве СУБД: SUBSTRING(строка, начальная_позиция, длина). Начальная позиция считается с 1. Если длина превышает оставшуюся часть строки, возвращается только существующая часть.
Пример извлечения кода товара из строки:
SELECT SUBSTRING(‘PRD-20251004-XY’, 5, 8);
Результат: 20251004. Здесь начинается с 5-го символа и извлекаются следующие 8 символов.
Для динамического определения позиции можно использовать CHARINDEX или INSTR. Например, извлечение домена из e-mail:
SELECT SUBSTRING(email, CHARINDEX(‘@’, email) + 1, LEN(email));
Если начальная позиция отрицательная или превышает длину строки, SUBSTRING возвращает пустую строку. При работе с Unicode рекомендуется использовать NVARCHAR для корректного извлечения символов.
В PostgreSQL аналогичная функция называется SUBSTRING(string FROM start FOR length), что позволяет точнее контролировать позицию и длину подстроки без преобразований.
При регулярном использовании SUBSTRING в фильтрах лучше проверять длину строки через LEN или LENGTH, чтобы избежать ошибок выхода за пределы строки.
Применение LEFT и RIGHT для выделения начала и конца строки

Функции LEFT и RIGHT позволяют извлекать фиксированное количество символов с начала или конца строки. Синтаксис простой и одинаков для большинства SQL-серверов:
LEFT(строка, количество_символов) – возвращает первые N символов строки.
RIGHT(строка, количество_символов) – возвращает последние N символов строки.
Примеры использования:
| Операция | SQL-запрос | Результат |
|---|---|---|
| Извлечение первых 5 символов | SELECT LEFT('Программирование', 5); |
Прогр |
| Извлечение последних 4 символов | SELECT RIGHT('Программирование', 4); |
ние |
| Применение к столбцу | SELECT LEFT(Имя, 3) FROM Пользователи; |
Возвращает первые 3 символа каждого имени |
| Комбинация LEFT и RIGHT | SELECT LEFT(RIGHT('Аналитика', 6), 3); |
лит |
Рекомендации при работе с функциями:
- Используйте
LEFTиRIGHTдля извлечения фиксированных частей строки, когда известна длина подстроки. - Для динамического выделения подстроки предпочтительнее сочетать с
CHARINDEXилиLEN, чтобы определить позицию и длину. - При работе с многобайтовыми кодировками (например, UTF-8) проверяйте, чтобы длина считалась корректно, иначе возможны обрезания символов.
Получение подстроки по позиции символа с CHARINDEX

Функция CHARINDEX позволяет определить позицию первого вхождения символа или подстроки внутри строки. Она часто используется совместно с SUBSTRING для извлечения части строки, начиная с найденного символа.
Синтаксис CHARINDEX:
CHARINDEX(expressionToFind, expressionToSearch [, start_location])expressionToFind– символ или подстрока, которую ищем.expressionToSearch– строка, в которой выполняется поиск.start_location– необязательный параметр, с какого символа начинать поиск (по умолчанию 1).
Пример извлечения имени пользователя из строки формата user@example.com:
SELECT SUBSTRING(email, 1, CHARINDEX('@', email) - 1) AS username
FROM users;
В этом случае:
CHARINDEX('@', email)возвращает позицию символа@.SUBSTRING(email, 1, CHARINDEX('@', email) - 1)извлекает все символы до@.
Если нужно получить подстроку после символа, смещаем стартовую позицию:
SELECT SUBSTRING(email, CHARINDEX('@', email) + 1, LEN(email)) AS domain
FROM users;
Рекомендации при использовании CHARINDEX:
- Учитывать возможность отсутствия искомого символа –
CHARINDEXвернет 0, иSUBSTRINGможет вызвать ошибку. - Для нескольких вхождений символа использовать
CHARINDEXс параметромstart_locationили функциюPATINDEX. - Комбинировать с
LENдля извлечения подстроки до конца строки.
Пример с выборкой домена второго уровня:
SELECT SUBSTRING(email, CHARINDEX('@', email) + 1, CHARINDEX('.', email, CHARINDEX('@', email)) - CHARINDEX('@', email) - 1) AS domain_level2
FROM users;
Использование CHARINDEX позволяет точно извлекать части строки по позициям ключевых символов без сложных регулярных выражений.
Комбинирование функций для извлечения динамических подстрок

В SQL часто возникает необходимость извлечь подстроку с переменной длиной и динамическим началом. Например, если требуется получить доменное имя из столбца email, стандартная функция SUBSTRING недостаточна без определения позиции символа ‘@’. Для этого применяется комбинация SUBSTRING и CHARINDEX:
SELECT SUBSTRING(email, CHARINDEX('@', email) + 1, LEN(email) - CHARINDEX('@', email)) AS domain FROM users;
В данном примере CHARINDEX вычисляет смещение символа ‘@’, а LEN обеспечивает корректную длину подстроки, что позволяет обрабатывать email любой длины.
Для извлечения текста между двумя различными разделителями применяют сочетание CHARINDEX и SUBSTRING. Например, чтобы получить слово между скобками в строке:
SELECT SUBSTRING(text, CHARINDEX('(', text) + 1, CHARINDEX(')', text) - CHARINDEX('(', text) - 1) AS inside_brackets FROM documents;
Если нужно динамически учитывать несколько вхождений, допустимо использовать CHARINDEX с третьим параметром, задающим стартовую позицию поиска. Это позволяет извлекать подстроки между повторяющимися разделителями:
SELECT SUBSTRING(text, CHARINDEX(',', text, CHARINDEX(',', text) + 1) + 1, CHARINDEX(',', text, CHARINDEX(',', text, CHARINDEX(',', text) + 1) + 1) - CHARINDEX(',', text, CHARINDEX(',', text) + 1) - 1) AS second_field FROM data;
Для оптимизации запросов с частыми извлечениями используют CTE или подзапросы, чтобы вычислять позиции один раз и применять их повторно, снижая нагрузку на базу и улучшая читаемость:
WITH positions AS (SELECT CHARINDEX('@', email) AS at_pos, LEN(email) AS len_val FROM users) SELECT SUBSTRING(email, at_pos + 1, len_val - at_pos) AS domain FROM users JOIN positions ON 1=1;
Комбинация функций SUBSTRING, CHARINDEX, LEN и PATINDEX обеспечивает гибкое извлечение подстрок в зависимости от содержания строк и их структуры, что делает обработку данных точной и динамичной.
Удаление лишних пробелов при выделении части строки

В SQL часто требуется извлечь подстроку без лишних пробелов в начале или конце. Для этого применяют функции TRIM, LTRIM и RTRIM. Например, при использовании SUBSTRING(column, start, length) результат может содержать пробелы, если исходная строка форматирована с фиксированной длиной.
Пример удаления пробелов с обеих сторон после выделения подстроки:
SELECT TRIM(SUBSTRING(column, 5, 10)) AS cleaned_substring FROM table_name;
Если необходимо удалить только пробелы слева или справа, применяют LTRIM или RTRIM соответственно:
SELECT LTRIM(SUBSTRING(column, 5, 10)) AS left_cleaned FROM table_name;
SELECT RTRIM(SUBSTRING(column, 5, 10)) AS right_cleaned FROM table_name;
Для баз данных, где поддерживаются функции REGEXP_REPLACE или REPLACE, можно удалять все лишние пробелы между словами:
SELECT REGEXP_REPLACE(TRIM(SUBSTRING(column, 5, 10)), '\s+', ' ') AS normalized_substring FROM table_name;
Совет: применять TRIM сразу после выделения подстроки, чтобы гарантировать корректную длину и отсутствие лишних символов при дальнейшей обработке или сравнении данных.
Обработка NULL и пустых значений при извлечении подстрок
В SQL функции работы со строками, такие как SUBSTRING, LEFT, RIGHT, возвращают NULL, если исходное значение NULL. Для предотвращения ошибок при вычислениях рекомендуется использовать COALESCE или ISNULL. Например: SELECT SUBSTRING(COALESCE(column, ''), 1, 5) FROM table – возвращает пустую строку вместо NULL.
При работе с пустыми строками (») SUBSTRING и аналогичные функции корректно возвращают подстроку длиной 0, без генерации ошибок. Однако вычисление длины или позиции символа может давать неожиданный результат. Для проверки можно использовать LEN(column) или LENGTH(column) в зависимости от СУБД, чтобы отделить NULL от пустой строки.
Для безопасного извлечения части строки из столбцов, содержащих как NULL, так и пустые строки, применяют конструкции вида: CASE WHEN column IS NULL OR column = '' THEN 'default' ELSE SUBSTRING(column, 1, 5) END. Это позволяет задать явное значение при отсутствии данных.
При использовании функций позиционирования символов (CHARINDEX, INSTR) важно проверять NULL перед вызовом, иначе результат тоже будет NULL. Комбинация COALESCE с проверкой длины предотвращает ошибки и упрощает формирование подстрок.
В PostgreSQL полезно использовать функцию NULLIF(column, '') для приведения пустой строки к NULL, если требуется единообразная обработка отсутствующих значений, особенно при объединении с другими таблицами или фильтрации.
Систематическое использование COALESCE, ISNULL и проверок длины обеспечивает предсказуемость результатов при извлечении подстрок, минимизирует ошибки и позволяет корректно обрабатывать смешанные данные, содержащие NULL и пустые строки.
Примеры выборки частей строк из таблиц с реальными данными

Для демонстрации работы с подстроками рассмотрим таблицу employees с колонками full_name, email и department. Основные функции SQL для выделения частей строки – SUBSTRING, LEFT, RIGHT, CHARINDEX (или INSTR в MySQL).
Примеры запросов:
- Выделение имени из полной строки «Иванов Иван»:
SELECT SUBSTRING(full_name, 1, CHARINDEX(' ', full_name) - 1) AS first_name
FROM employees;
SELECT SUBSTRING(full_name, CHARINDEX(' ', full_name) + 1, LEN(full_name)) AS last_name
FROM employees;
SELECT LEFT(email, 5) AS email_prefix
FROM employees;
SELECT SUBSTRING(email, CHARINDEX('@', email) + 1, LEN(email)) AS domain
FROM employees;
SELECT RIGHT(department, 3) AS dept_suffix
FROM employees;
Для таблицы orders с колонкой order_code можно выделять части кода по структуре:
- Выделение префикса кода заказа (первые 2 буквы):
- Выделение номера заказа (цифры после дефиса):
- Проверка последних символов для фильтрации определённой серии заказов:
SELECT LEFT(order_code, 2) AS code_prefix
FROM orders;
SELECT SUBSTRING(order_code, CHARINDEX('-', order_code) + 1, LEN(order_code)) AS order_number
FROM orders;
SELECT RIGHT(order_code, 2) AS series
FROM orders
WHERE RIGHT(order_code, 2) = 'A1';
Рекомендации при работе с реальными данными:
- Использовать TRIM или LTRIM/RTRIM для удаления лишних пробелов перед извлечением подстрок.
- Проверять наличие разделителей (например, пробелов или дефисов) с помощью CHARINDEX или INSTR, чтобы избежать ошибок.
- Для повторяющихся операций лучше создавать вычисляемые колонки с подстроками, чтобы ускорить выборку.
- Если структура строки нестандартная, применять CASE или регулярные выражения (в PostgreSQL – REGEXP_MATCHES) для точного выделения.
Вопрос-ответ:
Какая функция в SQL позволяет извлечь определённое количество символов из строки?
Для выделения части строки в SQL чаще всего используют функцию SUBSTRING (или SUBSTR в некоторых диалектах). Она позволяет указать начальную позицию и длину извлекаемого фрагмента. Например, выражение SUBSTRING(‘Пример текста’, 1, 6) вернёт ‘Пример’.
Можно ли получить часть строки, начиная с конца текста?
Да, для этого применяют функции, которые оперируют длиной строки, например, LEN или LENGTH. Если нужно взять последние N символов, можно использовать комбинацию функций: SUBSTRING(строка, LENGTH(строка)-N+1, N). Таким образом, вы получите кусок текста с конца строки.
Как извлечь часть строки между двумя известными символами?
Для подобных задач обычно используют функции поиска позиции символа, такие как CHARINDEX или POSITION, вместе с SUBSTRING. Сначала определяют позиции начального и конечного символа, затем передают их в SUBSTRING. Например, чтобы взять текст между скобками, находят позицию открывающей и закрывающей скобки и выделяют содержимое между ними.
Можно ли выделять часть строки без указания её длины заранее?
Да, если известна только начальная позиция, а длина фрагмента до конца строки. В этом случае SUBSTRING позволяет указать только начало и извлечь все символы до конца. Например, SUBSTRING(‘Пример текста’, 8) вернёт ‘текста’, начиная с 8-го символа до конца строки.
