T-SQL'de PadLeft işlevi


113

Aşağıdaki A tablosuna sahibim:

id
----
1
2
12
123
1234

idDeğerleri sıfırlarla sol-doldurmam gerekiyor :

id
----
0001
0002
0012
0123
1234

Bunu nasıl başarabilirim?

Yanıtlar:


197

Aradığın şeyin bu olabileceğine inanıyorum:

SELECT padded_id = REPLACE(STR(id, 4), SPACE(1), '0') 

FROM tableA

veya

SELECT REPLACE(STR(id, 4), SPACE(1), '0') AS [padded_id]

FROM tableA

Sözdizimini 2. örnekte test etmedim. Bunun% 100 işe yarayıp yaramadığından emin değilim - biraz ince ayar gerektirebilir - ancak istediğiniz çıktıyı nasıl elde edeceğinize dair genel bir fikir verir.

DÜZENLE

Yorumlarda listelenen endişeleri gidermek için ...

@ pkr298 - Evet STR yalnızca sayılar üzerinde çalışır ... OP'nin alanı bir kimliktir ... dolayısıyla yalnızca sayı.

@Desolator - Elbette bu işe yaramaz ... İlk parametre 6 karakter uzunluğunda. Şunun gibi bir şey yapabilirsiniz:

SELECT REPLACE(STR(id,
(SELECT LEN(MAX(id)) + 4 FROM tableA)), SPACE(1), '0') AS [padded_id] FROM tableA

bu teorik olarak hedef direklerini hareket ettirmelidir ... sayı büyüdükçe HER ZAMAN çalışmalıdır .... 1 veya 123456789 ...

Dolayısıyla, maksimum değeriniz 123456 ise ... 0000123456'yı ve minimum değeriniz 1 ise 0000000001'i görürsünüz.


4
STR () yalnızca sayılar (veya dize alanlarındaki sayılar) üzerinde çalışır. Bu kod, bir numaraya sahip olduğunu varsaydığınız ancak kayıtlardan birinde bozuk (sayısal olmayan) veriye sahip bir varchar alanında kullanıyorsanız bozulur. SAĞ () işlevi bu durumda bozulmayacaktır.
pkr298

1
Sayı daha STR(123456, 4)****

2
@Desolator Eklediğiniz senaryoyu kolaylaştırmak için bir yanıt ve düzeltme ekledim.
Patrick

67

SQL Server artık 2012 sürümünden itibaren FORMAT işlevini desteklemektedir , bu nedenle:

SELECT FORMAT(id, '0000') FROM TableA

hile yapacak.

Kimliğiniz veya sütununuz varcharbir içindeyse ve önce dönüştürdüğünüz bir sayıyı temsil ediyorsa:

SELECT FORMAT(CONVERT(INT,id), '0000') FROM TableA

Şık ve basit, teşekkürler! Orijinal sorunun tarihi göz önüne alındığında, bu artık resmi cevap olmalıdır;)
David Gunderson

1
İd bir
dizeyse

Üzgünüm ama olumsuz oy verdim çünkü bu yol GERÇEKTEN yavaş. Kabul edilen yanıt anında iken, 90 satırın üzerinde koşmak dört tam saniye sürdü. Bu çok büyük bir dezavantajdır ve FORMAT yalnızca bir veya iki kayıtta kullanılmalıdır, maks. Aksi takdirde, çok zayıf performansından dolayı işe yaramaz.
Gölge Sihirbazı Senin İçin Kulak

@ShadowWizard 1000 satırlık FORMAT kullanarak anlık performans görüyorum.
JohnnyHK

@JohnnyHK belki de masa tasarımı veya diğer db tuhaflıkları ile ilgili bir şey, ama yine de ... gerçek şu ki, diğer yol hızlıyken benim için gerçekten yavaştı.
Gölge Sihirbazı Senin İçin Kulak


43

Eski gönderi, ama belki bu birine yardımcı olur:

4 boş olmayan karakterle bitene kadar tamamlamak için:

SELECT RIGHT ('0000'+COLUMNNAME, 4) FROM TABLENAME;

10'a kadar tamamlamak için:

SELECT RIGHT ('0000000000'+COLUMNNAME, 10) FROM TABLENAME;

Sütunun sayısal olması durumunda, önce şu kodla varchar'a dönüştürün:

Select RIGHT('0000'+Convert(nvarchar(20), COLUMNNAME), 4)
From TABLENAME

Ve sayısal alanla 10'a kadar tamamlamak için:

SELECT RIGHT ('0000000000'+Convert(nvarchar(20), COLUMNNAME), 10) FROM TABLENAME;

1
@ SilverM-A, bir sayıdan önce 0 ekleyen bir yardımcı program yoktur, çünkü bunlar yine de yok sayılacaktır (sonuçta 0003 3'tür). Muhtemelen başarmak istediğiniz şey, bu sayıyı bir dizgeye (varchar) çevirmek ve sonra yukarıdaki ifadeyi kullanmaktır.
Marcelo Myara

1
@ SilverM-A, durum buysa, "CAST" komutunu kullanarak çevirin: SELECT RIGHT ('0000000000' + CAST (COLUMNAME AS VARCHAR), 10) FROM TABLENAME; Öyle mi?
Marcelo Myara

@MarceloMyara bu sadece bir yorumun değil, cevabın bir parçası olmalıdır. Şimdi kendim ekledim.
Gölge Sihirbazı Senin İçin Kulak

Not: Bu, gerçekten yavaşlayabilecek süslü işlevlerin olmadığı en etkili yanıttır. Bu yüzden ona fazladan ödül verdim.
Gölge Sihirbazı Sizin İçin Kulak

12

Bunu dene:

SELECT RIGHT(REPLICATE('0',4)+CAST(Id AS VARCHAR(4)),4) FROM [Table A]


5

Bu, dizeler, tam sayılar ve sayısallar için çalışır:

SELECT CONCAT(REPLICATE('0', 4 - LEN(id)), id)

4İstenilen uzunluk nerede . 4 haneden fazla sayılar için çalışır, NULLdeğerde boş dizge döndürür .


3

Hala ilgilenen biri varsa, bu makaleyi DATABASE.GUIDE'da buldum:
SQL Server'da Sol Dolgu - 3 LPAD () Eşdeğeri

Kısaca o yazıda bahsettiğimiz 3 yöntem var.
Diyelim ki id = 12 ve 0012 olarak görüntülenmesi gerekiyor.

Yöntem 1 - RIGHT () İşlevini Kullanma
İlk yöntem, baştaki bazı sıfırları ekledikten sonra dizenin yalnızca en sağdaki bölümünü döndürmek için RIGHT () işlevini kullanır.

SELECT RIGHT('00' + '12', 4);

Sonuç:
0012

Yöntem 2 - RIGHT () ve REPLICATE () Kombinasyonunu Kullanın
Bu yöntem önceki yöntemle hemen hemen aynıdır; tek fark, üç sıfırı REPLICATE () işleviyle değiştirmemdir:

SELECT RIGHT(REPLICATE('0', 2) + '12', 4);

Sonuç:
0012

Yöntem 3 - REPLACE () ve STR () Kombinasyonunu Kullanın
Bu yöntem, önceki yöntemlerden tamamen farklı bir açıdan gelir:

SELECT REPLACE(STR('12', 4),' ','0');

Sonuç:
0012

Makaleye göz atın, örneklerle daha ayrıntılı analizler var.


2

Bir değeri doldurmam gerektiğinde normalde kullandığım şey budur.

SET @PaddedValue = REPLICATE('0', @Length - LEN(@OrigValue)) + CAST(@OrigValue as VARCHAR)

1

Buna SQL sunucusunda bir işlevde ihtiyacım vardı ve Patrick'in cevabını biraz ayarladım.

declare @dossierId int = 123
declare @padded_id varchar(7)


set @padded_id = REPLACE(
              SPACE(7 - LEN(@dossierId)) + convert(varchar(7), @dossierId), 
              SPACE(1),  
              '0') 

SELECT @dossierId as '@dossierId'
      ,SPACE(LEN(@dossierId)) + convert(varchar(7)
      ,@dossierId) as withSpaces
      ,@padded_id as '@padded_id'

1

İşlev Oluştur:

    Create FUNCTION [dbo].[PadLeft]
      (
        @Text NVARCHAR(MAX) ,
        @Replace NVARCHAR(MAX) ,
        @Len INT
      )
RETURNS NVARCHAR(MAX)
AS
    BEGIN 


        DECLARE @var NVARCHAR(MAX) 

        SELECT @var = ISNULL(LTRIM(RTRIM(@Text)) , '')


        RETURN   RIGHT(REPLICATE(@Replace,@Len)+ @var, @Len)


    END

Misal:

Select dbo.PadLeft('123456','0',8)

Standartlarla ilgili bir noktaya değinmek gerekirse, IsNull kontrolü ile uğraşmam, eğer değer null ise, o zaman fonksiyon yerleşik fonksiyonların standart davranışı olduğundan, fonksiyon bu değer için yine de null döndürmelidir. Her şeyi boş olmayan bir değere dönüştürürsek, arayan kişi, başka türlü beklediği boş mantık işlemlerini artık kullanamayacaktır. (Tablolarımın çoğunda boş değer 'belirtilmedi' anlamına gelir ve varsayılan bir değer kullanılmalıdır.SELECT @var = LTRIM(RTRIM(@Text))
Chris Schaller

1

Bir işlev oluşturdum:

CREATE FUNCTION [dbo].[fnPadLeft](@int int, @Length tinyint)
RETURNS varchar(255) 
AS 
BEGIN
    DECLARE @strInt varchar(255)

    SET @strInt = CAST(@int as varchar(255))
    RETURN (REPLICATE('0', (@Length - LEN(@strInt))) + @strInt);
END;

Kullanın: dbo.fnPadLeft (123, 10) seçin

İade: 0000000123


0

Gerektiğinde oldukça ODBC uyumlu bir şey aşağıdaki olabilir:

select ifnull(repeat('0', 5 - (floor(log10(FIELD_NAME)) + 1)), '')
        + cast (FIELD as varchar(10))
  from TABLE_NAME

Bu, 10 tabanlı bir sayı için basamak miktarının günlüğünün integral bileşeni tarafından bulunabileceği gerçeğine dayanır. Bundan, onu istenen dolgu genişliğinden çıkarabiliriz. Tekrar null1'in altındaki değerler için dönecektir , bu yüzden ihtiyacımız var ifnull.


0

Çözümüm verimli değil, ancak değerlerin (banka çek numaraları ve havale referans no.) Bazı girişlerin alfa sayısal değerlere sahip olduğu ve uzunluk 6 karakterden küçükse doldurmak zorunda kaldığım varchar olarak depolandığı durumlarda bana yardımcı oldu.

Birisi aynı durumla karşılaşırsa paylaşmayı düşündüm

declare @minlen int = 6
declare @str varchar(20)

set @str = '123'
select case when len(@str) < @minlen then REPLICATE('0',@minlen-len(@str))+@str else @str end
--Ans: 000123

set @str = '1234'
select case when len(@str) < @minlen then REPLICATE('0',@minlen-len(@str))+@str else @str end
--Ans: 001234

set @str = '123456'
select case when len(@str) < @minlen then REPLICATE('0',@minlen-len(@str))+@str else @str end
--Ans: 123456

set @str = '123456789'
select case when len(@str) < @minlen then REPLICATE('0',@minlen-len(@str))+@str else @str end
--Ans: 123456789

set @str = '123456789'
select case when len(@str) < @minlen then REPLICATE('0',@minlen-len(@str))+@str else @str end
--Ans: 123456789


set @str = 'NEFT 123456789'
select case when len(@str) < @minlen then REPLICATE('0',@minlen-len(@str))+@str else @str end
--Ans: NEFT 123456789

0

Basit bir örnek olabilir

    DECLARE @number INTEGER
    DECLARE @length INTEGER
    DECLARE @char   NVARCHAR(10)
    SET @number = 1
    SET @length = 5
    SET @char = '0'

    SELECT FORMAT(@number, replicate(@char, @length))

0

Bunu yapmak için, istediğiniz çıktı karakter uzunluğunu belirleyebileceğiniz bir işlev oluşturdum:

CREATE FUNCTION [dbo].[udfLeadingZero]
(
        @String VARCHAR(MAX)
,       @Len INT
)
RETURNS VARCHAR(MAX)
BEGIN
    SET @String = RIGHT(REPLICATE('0',@Len)+@String,@Len)
RETURN @String
END
GO

Örnek sonuçlar


-5

Daha verimli yol şudur:

Select id, LEN(id)
From TableA
Order by 2,1 

The result :
id
----
1
2
12
123
1234

6
Bu, OP'lerin sıfırlarla doldurma sorusuna nasıl cevap verir?
Filburt
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.