Удалить последний символ в строке в T-SQL?

142

Как удалить последний символ в строке T-SQL?

Например:

'TEST STRING'

возвращаться:

'TEST STRIN'
Дэвид
источник

Ответы:

197

например

DECLARE @String VARCHAR(100)
SET @String = 'TEST STRING'

-- Chop off the end character
SET @String = 
     CASE @String WHEN null THEN null 
     ELSE (
         CASE LEN(@String) WHEN 0 THEN @String 
            ELSE LEFT(@String, LEN(@String) - 1) 
         END 
     ) END


SELECT @String
AdaTheDev
источник
72
В качестве альтернативы: ВЫБРАТЬ ВЛЕВО (YourColumnName, LEN (YourColumnName) - 1) ОТ YourTable
Кайл Б.
3
Спасибо за нулевой улов - ISNULL (LEFT (@String, LEN (@String) - 1), 'ErrMsg') решит
Volvox
2
@Volvox все равно будет генерировать исключение, если строка пустая, я изменяю ваш ответ для обработки этого сценария.
Имран Ризви,
108

Если по какой-то причине ваша логика столбца сложна (случай, когда ... then ... else ... end), то приведенные выше решения заставят вас повторить ту же логику в функции len (). Дублирование одной и той же логики превращается в беспорядок. Если это так, то стоит обратить внимание на это решение. Этот пример избавляется от последней нежелательной запятой. Наконец-то я нашел применение функции REVERSE.

select reverse(stuff(reverse('a,b,c,d,'), 1, 1, ''))
Билл Хёниг
источник
6
Обратите внимание, что этот код возвращается, NULLесли передана строка, которая короче диапазона удаления, указанного для STUFF. Оберните его в, ISNULLчтобы получить другое выходное значение для случая пустой строки.
Rozwel
12
Приятно использовать это с внешним применением, с путем для xml (''), чтобы исключить запятую в конце. awseome
Tracker1
Точно так же, как @ Tracker1. В отличие от всего, что связано с LEN (), это изящно работает (без каких-либо повторений) для пустой строки (особенно заключенной в ISNULL ())
gregmac 04
Удивительно, насколько жестоким иногда может быть SQL. Это невероятно.
eouw0o83hf 01
Спасибо, это помогло мне, в моем случае у меня был последний пробел, поэтому первый индекс - 2select reverse(stuff(reverse('a,b,c,d,'), 2, 1, ''))
Arngue
55

Попробуй это:

select substring('test string', 1, (len('test string') - 1))
Адриан
источник
@Adrien есть идеи, почему это дает тот же результат, что и select substring('test string', 0, len('test string'))?
Луи Ваверу
@Louis, синтаксис подстрока выглядит следующим образом : SUBSTRING ( expression ,start , length ). Теперь оба запроса возвращают то же самое, потому что нумерация основана на 1, что означает, что первый символ в выражении равен 1. Если start меньше 1, возвращаемое выражение начнется с первого символа, указанного в выражении. Источник
JS5
26

Если ваша строка пуста,

DECLARE @String VARCHAR(100)
SET @String = ''
SELECT LEFT(@String, LEN(@String) - 1)

тогда этот код вызовет сообщение об ошибке «Неверный параметр длины передан функции подстроки».

Вы можете справиться с этим следующим образом:

SELECT LEFT(@String, NULLIF(LEN(@String)-1,-1))

Он всегда будет возвращать результат, а в случае пустой строки - NULL.

Макс Грачев
источник
12

Это будет работать, даже если исходный текст / var равен нулю или пуст:

SELECT REVERSE(SUBSTRING(REVERSE(@a), 2, 9999))
Дэвид Роуч
источник
2
Это недооцененный комментарий, он быстрый, и для работы не нужно дважды выбирать строку.
Randall
7

Если ваш столбец есть, textа нет varchar, вы можете использовать это:

SELECT SUBSTRING(@String, 1, NULLIF(DATALENGTH(@String)-1,-1))
MicBehrens
источник
6

Если вы хотите сделать это за два шага, а не за три из REVERSE-STUFF-REVERSE, вы можете сделать разделитель списка одним или двумя пробелами. Затем используйте RTRIM, чтобы обрезать конечные пробелы, и REPLACE, чтобы заменить двойные пробелы на ','

select REPLACE(RTRIM('a  b  c  d  '),'  ', ', ')

Однако это не лучшая идея, если исходная строка может содержать внутренние пробелы.

Не уверен в производительности. Каждый REVERSE создает новую копию строки, но STUFF на треть быстрее, чем REPLACE.

также см. это

Дэрил
источник
6
@result = substring(@result, 1, (LEN(@result)-1))
Фаррух Салим
источник
2

вы можете создать функцию

CREATE FUNCTION [dbo].[TRUNCRIGHT] (@string NVARCHAR(max), @len int = 1)
RETURNS NVARCHAR(max)
AS
BEGIN
    IF LEN(@string)<@len
        RETURN ''
    RETURN LEFT(@string, LEN(@string) - @len)
END
Михаил Катрих
источник
2

Попробуй это

DECLARE @String VARCHAR(100)
SET @String = 'TEST STRING'
SELECT LEFT(@String, LEN(@String) - 1) AS MyTrimmedColumn
Абхишек Джайсвал
источник
2

Получить последнего персонажа

Right(@string, len(@String) - (len(@String) - 1))
Сэм
источник
Я не думаю, что это то, о чем он спрашивал, однако, это может быть полезно добавить в комментарий.
jimwise
3
Правильно (@string, 1).
GoalBased
2

Это довольно поздно, но, что интересно, еще никогда не упоминалось.

select stuff(x,len(x),1,'')

то есть:

take a string x
go to its last character
remove one character
add nothing
Джордж Менутис
источник
1

Мой ответ похож на принятый ответ, но он также проверяет наличие Null и Empty String.

DECLARE @String VARCHAR(100)

SET @String = 'asdfsdf1'

-- If string is null return null, else if string is empty return as it is, else chop off the end character
SET @String = Case @String when null then null else (case LEN(@String) when 0 then @String else LEFT(@String, LEN(@String) - 1) end ) end

SELECT @String
Имран Ризви
источник
0

Мне нравится ответ @Bill-Hoenig; однако я использовал подзапрос, и меня догнали, потому что функция REVERSE требовала двух наборов круглых скобок. Мне потребовалось время, чтобы понять это!

SELECT
   -- Return comma delimited list of all payment reasons for this Visit
   REVERSE(STUFF(REVERSE((
        SELECT DISTINCT
               CAST(CONVERT(varchar, r1.CodeID) + ' - ' + c.Name + ', ' AS VARCHAR(MAX))
          FROM VisitReason r1
          LEFT JOIN ReasonCode c        ON c.ID = r1.ReasonCodeID
         WHERE p.ID = r1.PaymentID
         FOR XML PATH('')
              )), 1, 2, ''))                        ReasonCode
  FROM Payments p
Hurleystylee
источник
Вы можете использовать внешнее / перекрестное применение для составной части запроса. Я использую это, чтобы получить набор флагов для родительского элемента.
Tracker1 04
0

Чтобы обновить запись путем обрезки последних N символов определенного столбца:

UPDATE tablename SET columnName = LEFT(columnName , LEN(columnName )-N) where clause
Manvendra_0611
источник
0

Попытайся :

  DECLARE @String NVARCHAR(100)
    SET @String = '12354851'
    SELECT LEFT(@String, NULLIF(LEN(@String)-1,-1))
Перец чили
источник
0
declare @string varchar(20)= 'TEST STRING'
Select left(@string, len(@string)-1) as Tada

выход:

Tada
--------------------
TEST STRIN
Миго
источник
0

Попробуй это,

DECLARE @name NVARCHAR(MAX) SET @name='xxxxTHAMIZHMANI****'SELECT Substring(@name, 5, (len(@name)-8)) as UserNames

И на выходе будет THAMIZHMANI

Тамижмани
источник
-1
declare @x varchar(20),@y varchar(20)
select @x='sam'
select 
case when @x is null then @y
      when @y is null then @x
      else @x+','+@y
end


go

declare @x varchar(20),@y varchar(20)
select @x='sam'
--,@y='john'
DECLARE @listStr VARCHAR(MAX)   

SELECT @listStr = COALESCE(@x + ', ' ,'') +coalesce(@y+',','')
SELECT left(@listStr,len(@listStr)-1)
Джули
источник