Usuwanie wiodących zer z pola w instrukcji SQL

99

Pracuję nad zapytaniem SQL, które odczytuje z bazy danych SQLServer, aby utworzyć plik wyodrębnienia. Jedno z wymagań dotyczących usunięcia wiodących zer z określonego pola, które jest VARCHAR(10)polem prostym . Na przykład, jeśli pole zawiera „00001A”, instrukcja SELECT musi zwrócić dane jako „1A”.

Czy w SQL jest sposób, aby w ten sposób łatwo usunąć wiodące zera? Wiem, że jest RTRIMfunkcja, ale wydaje się, że usuwa tylko spacje.

Tim C.
źródło
3
Głos za odpowiedzią Davida Walkera na stackoverflow.com/a/11129399/1635441 można znaleźć w wysłanej odpowiedzi Arvo: stackoverflow.com/a/662437/1635441
ramizmoh

Odpowiedzi:

152
select substring(ColumnName, patindex('%[^0]%',ColumnName), 10)
Ian Horwill
źródło
8
Będzie to powodować problemy, gdy ciąg składa się w całości z „0”, ponieważ nigdy nie będzie pasował do znaku innego niż „0”.
Cade Roux,
Prawdziwe. W tym przypadku zwróci cały niezmodyfikowany ciąg zer. Jeśli jest to problem, zwracana wartość patindex będzie musiała zostać przetestowana względem zera.
Ian Horwill
@Zapnologica: Nie. Musiałbyś to umieścić w instrukcji „update TableName set ColumnName = ...”.
Ian Horwill
Jasne, jeśli używasz instrukcji aktualizacji.
Srivastav
1
Przed skorzystaniem z tego rozwiązania spróbuj zapoznać się z odpowiedzią Arvo zamieszczoną tutaj
OscarSosa
27
select replace(ltrim(replace(ColumnName,'0',' ')),' ','0')
MTZ
źródło
Otrzymałem informację „Funkcja zamień wymaga 3 argumentów”. Uważam, że powinien przeczytać select replace (ltrim (replace (ColumnName, '0', '')), '', '0')
brentlightsey
5
To się nie powiedzie, jeśli wartość zawiera spację. Przykład: „0001 B” powinno stać się „1 B”, ale zamiast tego stanie się „10B”.
Omaer
1
Jak wspomniano w @Omaer, nie jest to bezpieczne, jeśli w ciągu znaków są spacje. Ulepszone rozwiązanie - najpierw zamień spacje na znaki, które prawdopodobnie nie pojawią się na wejściu, a po 0-ltrim przywróć te znaki do spacji później. Ostatecznie wygląda na dość skomplikowane :( Przykład: select replace (replace (ltrim (replace (replace ('000309933200,00 USD' ',' ',' | '),' 0 ',' ')),' ',' 0 '),' | ',' ') -> 309933200,00 USD
Robert Lujo
5
select substring(substring('B10000N0Z', patindex('%[0]%','B10000N0Z'), 20), 
    patindex('%[^0]%',substring('B10000N0Z', patindex('%[0]%','B10000N0Z'), 
    20)), 20)

zwraca N0Z, to znaczy pozbywa się wiodących zer i wszystkiego, co jest przed nimi.

Nat
źródło
5
Jak to jest wiodące 0, jeśli coś jest przed nim?
xxbbcc,
4

Miałem taką samą potrzebę i użyłem tego:

select 
    case 
        when left(column,1) = '0' 
        then right(column, (len(column)-1)) 
        else column 
      end
ekc
źródło
3

Jeśli chcesz, aby zapytanie zwróciło 0 zamiast ciągu zer lub dowolnej innej wartości w tym zakresie, możesz przekształcić to w instrukcję case, taką jak ta:

select CASE
      WHEN ColumnName = substring(ColumnName, patindex('%[^0]%',ColumnName), 10) 
       THEN '0'
      ELSE substring(ColumnName, patindex('%[^0]%',ColumnName), 10) 
      END
Kathryn Wilson
źródło
2

Możesz użyć tego:

SELECT REPLACE(LTRIM(REPLACE('000010A', '0', ' ')),' ', '0')
Stelian
źródło
0

Możesz tego spróbować - w razie potrzeby należy usunąć tylko zera wiodące:

DECLARE @LeadingZeros    VARCHAR(10) ='-000987000'

SET @LeadingZeros =
      CASE WHEN PATINDEX('%-0', @LeadingZeros) = 1   THEN 
           @LeadingZeros
      ELSE 
           CAST(CAST(@LeadingZeros AS INT) AS VARCHAR(10)) 
      END   

SELECT @LeadingZeros

Możesz też po prostu zadzwonić

CAST(CAST(@LeadingZeros AS INT) AS VARCHAR(10)) 
Shailendra Mishra
źródło
0

Oto funkcja wartości skalarnej SQL, która usuwa zera wiodące z łańcucha:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:      Vikas Patel
-- Create date: 01/31/2019
-- Description: Remove leading zeros from string
-- =============================================
CREATE FUNCTION dbo.funRemoveLeadingZeros 
(
    -- Add the parameters for the function here
    @Input varchar(max)
)
RETURNS varchar(max)
AS
BEGIN
    -- Declare the return variable here
    DECLARE @Result varchar(max)

    -- Add the T-SQL statements to compute the return value here
    SET @Result = @Input

    WHILE LEFT(@Result, 1) = '0'
    BEGIN
        SET @Result = SUBSTRING(@Result, 2, LEN(@Result) - 1)
    END

    -- Return the result of the function
    RETURN @Result

END
GO
Vikas
źródło
-1

Usunięcie początkowego 0 z miesiąca następującego na pewno zadziała.

SELECT replace(left(Convert(nvarchar,GETDATE(),101),2),'0','')+RIGHT(Convert(nvarchar,GETDATE(),101),8) 

Po prostu zastąp GETDATE()polem daty swojej tabeli.

Afzal
źródło
3
Jak dokładnie to odpowiada na pytanie?
deutschZuid
-2

możesz tego spróbować SELECT REPLACE(columnname,'0','') FROM table

Madhurupa Moitra
źródło
3
Spowoduje to usunięcie 0 niezależnie od jego pozycji. Pytanie dotyczy tylko wiodących.
Sunil
-2

Aby usunąć początkowe 0, możesz pomnożyć kolumnę liczbową przez 1 Np .: Wybierz (ColumnName * 1)

Krin
źródło
3
Co równa się „1A” * 1?
Jonathan Rys
co to będzie 10 * 1?
RATAN KUMAR
W pytaniu stwierdzono, że typ kolumny to VARCHAR (10), dlatego mnożenie nie jest możliwe.
y434y
-2
select replace(replace(rtrim(replace(replace(replace(replace(ltrim(replace(replace([COLUMN],' ','[Ltrim]'),[Ltrim],' ')),' ',[Ltrim]),'[Ltrim]',' '),' ','[Rtrim]'),[Rtrim],' ')),' ',[Rtrim]),'[Rtrim]',' ') As Result

To jest skrypt Sql, który emuluje funkcjonalność polecenia TRIM w tsql sprzed 2017 roku, jest w zasadzie taki sam jak inne zalecenia, ale inne zastępują pojedynczym nietypowym znakiem, który nadal może wystąpić, „[Rtrim]” lub „[ Ltrim] 'może nadal występować w tekście, ale zastąpienie kapelusza unikalnym tekstem, na przykład Guid, rozwiązałoby ten problem.

nie testowałem tego pod kątem szybkości

Boczek
źródło
-3

Zapożyczyłem z powyższych pomysłów. To nie jest ani szybkie, ani eleganckie. ale to jest dokładne.

WALIZKA

WHEN left(column, 3) = '000' THEN right(column, (len(column)-3))

WHEN left(column, 2) = '00' THEN right(a.column, (len(column)-2))

WHEN left(column, 1) = '0' THEN right(a.column, (len(column)-1))

ELSE 

KONIEC

Brian Ellison
źródło
Nie jest również dynamiczna, aby zezwolić na więcej niż 3 zera.
JoeFletch
-3
select CASE
         WHEN TRY_CONVERT(bigint,Mtrl_Nbr) = 0
           THEN ''
           ELSE substring(Mtrl_Nbr, patindex('%[^0]%',Mtrl_Nbr), 18)
       END
Lynn Caveny
źródło
1
Powinieneś wyjaśnić swoje odpowiedzi, a nie tylko pojedynczy fragment kodu. Ponadto sformatuj kod jako kod (u góry pola tekstowego znajduje się przycisk).
David Heyman
-4
select ltrim('000045', '0') from dual;

LTRIM
-----
45

To powinno wystarczyć.

user3809240
źródło
2
Nie ma przeciążenia dla serwera sql.
BillRob
W PostgreSQL wystarczyło pisać select trim(leading '0' from '001A');, ale OP pytał o SQL Server.
y434y