Удалить последний символ в строке в 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

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))

6

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

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

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

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

также см. это




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

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

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

Вы можете использовать внешнее / перекрестное применение для составной части запроса. Я использую это, чтобы получить набор флагов для родительского элемента.
Tracker1 04

0

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

UPDATE tablename SET columnName = LEFT(columnName , LEN(columnName )-N) where clause


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)
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.