Usunąć ostatni znak w ciągu w T-SQL?

139

Jak usunąć ostatni znak w ciągu T-SQL?

Na przykład:

'TEST STRING'

wracać:

'TEST STRIN'
Daveed
źródło

Odpowiedzi:

195

na przykład

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
źródło
71
Alternatywnie wybrać Lewy (YourColumnName, DŁ (YourColumnName) - 1) z YourTable
Kyle B.
3
Dzięki za zerowy haczyk - ISNULL (LEFT (@String, LEN (@String) - 1), 'ErrMsg') rozwiąże się
Volvox
2
@Volvox nadal będzie zgłaszać wyjątek, jeśli ciąg jest pusty, modyfikuję twoją odpowiedź, aby obsłużyć ten scenariusz.
Imran Rizvi
106

Jeśli z jakiegoś powodu logika Twojej kolumny jest złożona (przypadek kiedy ... then ... else ... end), powyższe rozwiązania powodują, że musisz powtórzyć tę samą logikę w funkcji len (). Powielanie tej samej logiki staje się bałaganem. Jeśli tak jest, to warto zwrócić uwagę na to rozwiązanie. Ten przykład usuwa ostatni niechciany przecinek. W końcu znalazłem zastosowanie funkcji REVERSE.

select reverse(stuff(reverse('a,b,c,d,'), 1, 1, ''))
Bill Hoenig
źródło
6
Zwróć uwagę, że ten kod zwraca, NULLjeśli przekazano ciąg, który jest krótszy niż zakres usuwania określony dla STUFF. Zawiń go w an, ISNULLaby uzyskać inną wartość wyjściową dla pustej wielkości łańcucha.
Rozwel
11
Fajnie, używając tego z zewnętrzną aplikacją, ze ścieżką for xml („”), aby wyeliminować końcowy przecinek. awseome
Tracker1
Również w taki sam sposób, jak @ Tracker1. W przeciwieństwie do wszystkiego, co zawiera LEN (), ten wdzięcznie działa (bez powtarzania czegokolwiek) dla pustego ciągu (szczególnie opakowanego w ISNULL ())
gregmac
To naprawdę niezwykłe, jak brutalny może być czasami SQL. To jest niesamowite.
eouw0o83hf
Dzięki, pomogło mi, w moim przypadku miałem ostatnią spację więc pierwszy indeks to 2select reverse(stuff(reverse('a,b,c,d,'), 2, 1, ''))
Arngue
52

Spróbuj tego:

select substring('test string', 1, (len('test string') - 1))
Adrien
źródło
@Adrien ma jakiś pomysł, dlaczego wydaje się to dawać taki sam wynik jak select substring('test string', 0, len('test string'))?
Louis Waweru
@Louis składnia podciąg jest w następujący sposób: SUBSTRING ( expression ,start , length ). Teraz oba zapytania zwracają to samo, ponieważ numeracja jest oparta na 1, co oznacza, że ​​pierwszy znak w wyrażeniu to 1. Jeśli początek jest mniejszy niż 1, zwrócone wyrażenie rozpocznie się od pierwszego znaku określonego w wyrażeniu. Źródło
JS5,
26

Jeśli twój ciąg jest pusty,

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

wtedy ten kod spowoduje komunikat o błędzie „Nieprawidłowy parametr długości przekazany do funkcji podciągu”.

Możesz sobie z tym poradzić w ten sposób:

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

Zawsze zwróci wynik i NULL w przypadku pustego ciągu.

Max Grachev
źródło
10
select left('TEST STRING', len('TEST STRING')-1)
greg121
źródło
9

To zadziała nawet wtedy, gdy tekst źródłowy / var ma wartość null lub jest pusty:

SELECT REVERSE(SUBSTRING(REVERSE(@a), 2, 9999))
David Roach
źródło
2
To jest niedoceniony komentarz, jest szybki i nie musi dwukrotnie wybierać ciągu, aby działał.
Randall,
7

Jeśli twój coloumn jest texti nie varchar, możesz użyć tego:

SELECT SUBSTRING(@String, 1, NULLIF(DATALENGTH(@String)-1,-1))
MicBehrens
źródło
5

Jeśli chcesz to zrobić w dwóch krokach, zamiast trzech z ODWRÓĆ-STUFF-ODWRÓĆ, możesz ustawić separator listy w postaci jednej lub dwóch spacji. Następnie użyj RTRIM, aby przyciąć końcowe spacje i REPLACE, aby zamienić podwójne spacje na ','

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

Jednak nie jest to dobry pomysł, jeśli oryginalny ciąg może zawierać spacje wewnętrzne.

Nie jestem pewien co do wydajności. Każde REVERSE tworzy nową kopię ciągu, ale STUFF jest o jedną trzecią szybsze niż REPLACE.

zobacz też to

Daryl
źródło
5
@result = substring(@result, 1, (LEN(@result)-1))
farrukh saleem
źródło
5

Mogę to zasugerować -hack-;).

select 
    left(txt, abs(len(txt + ',') - 2))
from 
    t;

SQL Server Fiddle Demo

shA.t
źródło
2

możesz stworzyć funkcję

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
Mihail Katrikh
źródło
2

Spróbuj tego

DECLARE @String VARCHAR(100)
SET @String = 'TEST STRING'
SELECT LEFT(@String, LEN(@String) - 1) AS MyTrimmedColumn
Abhishek Jaiswal
źródło
2

Zdobądź ostatnią postać

Right(@string, len(@String) - (len(@String) - 1))
Sam
źródło
Nie wydaje mi się jednak, żeby o to pytał - może jednak przydać się komentarz.
jimwise
3
just Right (@string, 1).
GoalBased
1

Moja odpowiedź jest podobna do zaakceptowanej odpowiedzi, ale sprawdza również wartość Null i 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
Imran Rizvi
źródło
1

To dość późno, ale co ciekawe, jeszcze nigdy nie wspomniano.

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

to znaczy:

take a string x
go to its last character
remove one character
add nothing
George Menoutis
źródło
0

Uwielbiam odpowiedź @ bill-hoenig; jednak korzystałem z podzapytania i zostałem złapany, ponieważ funkcja REVERSE potrzebowała dwóch zestawów nawiasów. Zajęło mi trochę czasu, zanim to rozgryzłem!

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
źródło
Możesz chcieć użyć zewnętrznego / krzyżowego zastosowania dla złożonej części zapytania. Używam tego, aby uzyskać zestaw flag dla elementu nadrzędnego.
Tracker1
0

Aby zaktualizować rekord przez obcięcie ostatnich N znaków z określonej kolumny:

UPDATE tablename SET columnName = LEFT(columnName , LEN(columnName )-N) where clause
Manvendra_0611
źródło
0

Spróbuj :

  DECLARE @String NVARCHAR(100)
    SET @String = '12354851'
    SELECT LEFT(@String, NULLIF(LEN(@String)-1,-1))
Chilli
źródło
0
declare @string varchar(20)= 'TEST STRING'
Select left(@string, len(@string)-1) as Tada

wynik:

Tada
--------------------
TEST STRIN
Migo
źródło
0

Spróbuj tego,

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

A wynik będzie podobny do THAMIZHMANI

Thamizhmani
źródło
-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)
Julie
źródło