Функции STR, SPACE, LTRIM и RTRIM
Функция STR() преобразует число к его символьному представлению:
STR(<число с плавающей точкой> [, <длина> [, <число десятичных знаков> ] ] )
При этом преобразовании выполняется округление, а длина задает длину результирующей строки. Например,
STR(3.3456, 5, 1) | 3.3 |
STR(3.3456, 5, 2) | 3.35 |
STR(3.3456, 5, 3) | 3.346 |
STR(3.3456, 5, 4) | 3.346 |
STR(12345,4,0) | **** |
Обратите внимание, что если полученное строковое представление числа меньше заданной длины, то добавляются лидирующие пробелы. Если же результат больше заданной длины, то усекается дробная часть (с округлением); в случае же целого числа получаем соответствующее число звездочек «*»:
Кстати, по умолчанию используется длина в 10 символов.
Имея в виду, что год представлен четырьмя цифрами, напишем:
SELECT name, STUFF(name, 6, LEN(name), '_'+STR(launched, 4))
FROM Ships;
[[ column ]] |
---|
NULL [[ value ]] |
Уже почти все правильно (мы продолжаем решать задачу, начатую здесь). Осталось учесть случай, когда число символов в имени менее 6, так как в этом случае функция STUFF дает NULL. Ну что ж, вытерпим до конца мучения, связанные с использованием этой функции в данном примере, попутно применив еще одну строковую функцию.
Добавим конечные пробелы, чтобы длина имени была заведомо больше 6. Для этого имеется специальная функция SPACE(<число пробелов>):
SELECT name, STUFF(name + SPACE(6), 6, LEN(name), '_'+STR(launched,4))
FROM Ships;
[[ column ]] |
---|
NULL [[ value ]] |
Функции LTRIM(<строковое выражение>) и RTRIM(<строковое выражение>) Отсекают, соответственно, лидирующие и конечные пробелы строкового выражения, которое неявно приводится к типу varchar.
Пусть требуется построить такую строку:
<имя пассажира>_<идентификатор пассажира>
на базе таблицы Passenger. Если мы напишем:
SELECT name + '_' + CAST(id_psg AS VARCHAR)
FROM Passenger;
[[ column ]] |
---|
NULL [[ value ]] |
то в результате получим что-то типа:
A _1 |
Это связано с тем, что столбец name имеет тип CHAR(30). Для этого типа короткая строка дополняется пробелами до заданного размера (у нас это 30 символов). Здесь нам как раз и поможет функция RTRIM:
SELECT RTRIM(name) + '_' + CAST(id_psg AS VARCHAR)
FROM Passenger;
[[ column ]] |
---|
NULL [[ value ]] |
Для усечения концевых пробелов в SQL Server изначально имелось две функции - LTRIM и RTRIM - для усечения пробелов слева и справа соответственно. Чтобы удалить пробелы с обеих сторон строки, последовательно применялись обе функции (в примере для наглядности используется функция DATALENGTH, возвращающая число символов с учетом пробелов):
declare @s varchar(10) =' x ' -- слева 2 пробела, справа - 1
select datalength(@s) s, datalength(ltrim(@s)) ls,
datalength(rtrim(@s)) rs, datalength(ltrim(rtrim(@s))) bs;
s | ls | rs | bs |
---|---|---|---|
4 | 2 | 3 | 1 |
Начиная с версии SQL Server 2017, к ним добавилась новая функция - TRIM, которая выполняет усечение с обеих сторон строки-аргумента:
select datalength(@s) s, datalength(trim(@s)) ts;
s | ts |
---|---|
4 | 1 |
Кроме того, функция TRIM приобрела дополнительный функционал - возможность усекать произвольные концевые символы.
При этом усекаемые символы можно задавать списком, перечисляя их в произвольном порядке. Усекаться (с обеих сторон) будут все входящие в список символы, пока не появится “посторонний”, т.е. не входящий в список. Лучше всего продемонстрировать сказанное на примере.
declare @s1 varchar(10)='xxaxbxy'
select trim('yx' from @s1) ts1, trim('x' from @s1) ts2;
ts1 | ts2 |
---|---|
axb | axbxy |
Конечно, это еще не стандартное поведение, но уже близко. А вот что говорит стандарт относительно функции TRIM:
< trim function> ::= TRIM < left paren> < trim operands> < right paren>
< trim operands> ::= [ [ < trim specification> ] [ < trim character> ] FROM ] < trim source>
< trim source> ::= < character value expression>
< trim specification> ::= LEADING | TRAILING | BOTH
< trim character> ::= < character value expression>
MySQL
В MySQL используется стандартный синтаксис функции TRIM. При этом, в отличие от SQL Server, удаляется указанная подстрока, а не все символы из списка:
SELECT TRIM(LEADING 'xy' FROM 'xyxybarxyx') ls,
TRIM(TRAILING 'xy' FROM 'xyxybarxyx') rs,
TRIM(BOTH 'yx' FROM 'xyxybarxyx') bs;
[[ column ]] |
---|
NULL [[ value ]] |
ls | rs | bs |
---|---|---|
barxyx | xyxybarxyx | xyxybarx |
PostgreSQL
PostgreSQL сочетает поведение MySQL и SQL Server, т.е. удаляются все символы из списка:
SELECT TRIM(LEADING 'xy' FROM 'xyxybarxyx') ls,
TRIM(TRAILING 'xy' FROM 'xyxybarxyx') rs,
TRIM(BOTH 'yx' FROM 'xyxybarxyx') bs;
[[ column ]] |
---|
NULL [[ value ]] |
ls | rs | bs |
---|---|---|
barxyx | xyxybar | bar |
Oracle
Oracle допускает усечение только одного символа, а не подстроки или символов из списка:
SELECT TRIM(LEADING 'x' FROM 'xxybarxyx') ls,
TRIM(TRAILING 'x' FROM 'xxybarxyx') rs,
TRIM(BOTH 'x' FROM 'xxybarxyx') bs
from dual;
[[ column ]] |
---|
NULL [[ value ]] |
ls | rs | bs |
---|---|---|
ybarxyx | xxybarxy | ybarxy |