SQL Server'da önde gelen sıfırlarla doldurarak Numaraları biçimlendirme


119

SQL Server 2000 tarafından 10 yıla yakın bir süredir kullanılan eski bir SQL tablomuz var.

İçinde, char(6)kimden 000001tarihine kadar çalışan rozet numaralarımız saklanır 999999.

Şu anda bir web uygulaması yazıyorum ve çalışan rozet numaralarını saklamam gerekiyor.

Yeni tablomda, kısayolu alıp eski tabloyu kopyalayabilirim, ancak intdeğerlerini 'den' 1e kadar saklayarak daha iyi veri aktarımı, daha küçük boyut, vb. Umuyorum 999999.

C #'da, introzet numarası için bir değeri hızlı bir şekilde biçimlendirebilirim.

public static string GetBadgeString(int badgeNum) {
  return string.Format("{0:000000}", badgeNum);
  // alternate
  // return string.Format("{0:d6}", badgeNum);
}

Döndürülen değeri de biçimlendirmek için bu basit SQL sorgusunu nasıl değiştirebilirim?

SELECT EmployeeID
FROM dbo.RequestItems
WHERE ID=0

Eğer EmployeeID7135 ise, bu sorgu dönmelidir 007135.


Liderler 0bu alan için önemli olduğuna göre, neden onu INThiç olarak değiştirelim ?
Oded

2
SQL Server 2012 sonundaFORMAT C # :-) gibi bir işleve sahip olacak
marc_s

1
@Oden: intDeğerler bundan önemli ölçüde daha az yer kaplar char(6)ve üretilen parça başına bu girişlerin birden fazla olması gerekir. Verimlilik.
jp2code

Bir sorun yaşamadan önce optimizasyon yapıyor musunuz?
Oded

4
Bakalım, bir milyona kadar rozet numaranız var ve DATALENGTH()her biri iki bayt tasarruf edebileceğinizi (göre ) anlıyorsunuz . Sütun bir dizinde olabileceğinden, 2MB'den fazla tasarruf ediyor olabilirsiniz. Ve diğer sütunlar eklendiğinde, bu 2 bayt, bir satırın uzunluğunu, satır başına 4KB sayfa kaydedecek kadar azaltmak için yeterli olabilir. Bu bir mobil platformda mı barındırılacak, yoksa dikkatinizi verimsiz bir alana mı odaklayacaksınız?
HABO

Yanıtlar:


172

6 sayısını, toplam uzunluğunuz ne olursa olsun değiştirin:

SELECT REPLICATE('0',6-LEN(EmployeeId)) + EmployeeId

Sütun bir INT ise, onu dolaylı olarak bir VARCHAR'a dönüştürmek için RTRIM'i kullanabilirsiniz.

SELECT REPLICATE('0',6-LEN(RTRIM(EmployeeId))) + RTRIM(EmployeeId)

Ve bu 0'ları kaldırıp 'gerçek' numarayı geri almak için kod:

SELECT RIGHT(EmployeeId,(LEN(EmployeeId) - PATINDEX('%[^0]%',EmployeeId)) + 1)

1
+1 Bana 0'ları nasıl kaldıracağımı bile gösterdin! Bunu bir test edeyim, bir cevap olarak işaretleyeceğim.
jp2code

1
sıfırları kaldırmak için koda ihtiyacınız yoktur, sadece int atayın veya bir int'e dönüştürün; bunlar otomatik olarak kaldırılacaktır.
Jimbo

2
Bu sadece aktarılan değer bir dizge ise işe yarar, bir tamsayı geçerseniz
girdiğiniz

2
Eski olmasına rağmen ... "+ EmployeeID" yerine "+ convert (varchar, EmployeeID)" kullanmak int sorununu
çözmeli

3
EmployeeId 6 basamaktan büyük olmadığı sürece bu iyi bir yoldur ve NULL sonucuna neden olur. İletişim işlevi cevaptır: SELECT CONCAT (REPLICATE ('0', 6-LEN (CONVERT (varchar, EmployeeId))), EmployeeId)
Mahmoud Moravej

125

FORMAT işlevini kullanmanız yeterlidir (SQL Server 2012 veya daha yenisinde çalışır):

SELECT FORMAT(EmployeeID, '000000')
FROM dbo.RequestItems
WHERE ID=0 

Referans: http://msdn.microsoft.com/en-us/library/hh213505.aspx


1
Bu eski bir sorudur - SQL Server 2012 çıkmadan önce.
jp2code

19
Yine de, bu balonu şimdi biraz daha yakın görmek istiyorum.
Dave Haynes

4
Sadece merak eden varsa diye. Formatveri türünü korumaz ancak örtük olarak nvarchar'a dönüştürür:select sql_variant_property(50, 'BaseType'), sql_variant_property(format(50, N'00000'), 'BaseType')
Ralph

2
Bu yol en basit ve IMHO en iyi çözümdür.
Robert Lujo

Büyük veri kümesi için kullanıyorsanız bu işlevi unutmayın
amd

33

Prosedürünüzü bu şekilde değiştirebilirsiniz

SELECT Right('000000' + CONVERT(NVARCHAR, EmployeeID), 6) AS EmpIDText, 
       EmployeeID
FROM dbo.RequestItems 
WHERE ID=0 

Ancak bu, sizin EmployeeIDsayısal bir değerinizin olduğunu varsayar ve bu kod, sonucu bir dizeye dönüştürür, orijinal sayısal değeri tekrar eklemenizi öneririm

EDIT Tabii ki yukarıdaki soruyu dikkatlice okumadım. Alanın bir char(6)EmployeeID olduğunu söyler, sayısal bir değer değildir. Bu cevabın başlı başına bir değeri olsa da, yukarıdaki soruya doğru cevap değildir.


Bence bunu yapmanın en temiz yolu bu. Teşekkürler
iheartcsharp

Bu '000000'gerçekten gerekli mi ..? '0'ayrıca iyi çalışıyor. Sadece bir 0 kullanmak güvenli midir?
shashwat

1
Operatör sonuç olarak 6 karakter uzunluğunda bir dizi istedi. Özellikle EmployeeID 7135 ise, bu sorgu 007135 döndürmelidir . Sadece bir '0' döner kullanma 07135değil 007135. Tüm fikir EmpicipedID 0dönüştürülmüş tüm dizelerden oluşan 6 karakterli bir dizeye birleştirmek , ardından sağ kenardan BAŞLAYARAK 6 karakter almaktır. Kimlik ne uzunlukta olursa olsun, yukarıdaki yöntem her zaman 6 karakter uzunluğuna ulaşmak için gereken sıfır karakter sayısına sahip bir dize döndürür
Steve

Bu 5 sıfır olabilir '00000'çünkü EmployeeIDen az bir rakam içerecektir. Ancak REPLICATE()işlev diğer yanıtlarda olduğu gibi daha uygun görünüyor
nosklo

26

İnt'i DÖNÜŞTÜRMEKTEN nefret ediyorum ve bu çok daha basit görünüyor. Yalnızca bir dize dönüşümü ve basit bir ekleme olduğu için daha iyi performans gösterebilir.

SAĞ seçin (1000000 + ÇalışanKimliği, 6) ...

"1000000" de en az gereken boyut kadar sıfır olduğundan emin olun.


11

Hepsini tek bir yere gönderiyorum, hepsi benim için 4 önde sıfır ile doldurmak için çalışıyor :)

declare @number int =  1;
print right('0000' + cast(@number as varchar(4)) , 4)
print right('0000' + convert(varchar(4), @number) , 4)
print right(replicate('0',4) + convert(varchar(4), @number) , 4)
print  cast(replace(str(@number,4),' ','0')as char(4))
print format(@number,'0000')

Bu, gerekli tüm seçenekleri kapsar. Teşekkür ederim.
kyurthich

6

Tamlık için başka bir yol.

DECLARE @empNumber INT = 7123
SELECT STUFF('000000', 6-LEN(@empNumber)+1, LEN(@empNumber), @empNumber)

Veya sorgunuza göre

SELECT STUFF('000000', 6-LEN(EmployeeID)+1, LEN(EmployeeID), EmployeeID) 
         AS EmployeeCode
FROM dbo.RequestItems
WHERE ID=0

@ jp2code - Gerekirse StackOverflow ne kadar okumak onun işbirliği içinde bir wiki gibi düzenlenebilir - - onun değil sizin sorunuzu en kısa sürede bunu gönderdiniz olarak! Yaygın olarak düzenlenen şeyler, önceden teşekkür etmek ve zayıf dilbilgisi / büyük harf kullanımı gibi aşırı "tüyler" tir.
Jamiec

5

2012 sürümünden itibaren kullanabilirsiniz

SELECT FORMAT(EmployeeID,'000000')
FROM dbo.RequestItems
WHERE ID=0

4

Olabildiğince temiz ve değişkenlerle değiştirme kapsamı sağlar:

Select RIGHT(REPLICATE('0',6) + EmployeeID, 6) from dbo.RequestItems
WHERE ID=0

Eğer EmployeeIDkolon olarak tanımlanır intve ardından + operatör ek yerine birleştirme gibi ve sıfır kaybolur, böylece tedavi edilecektir. Kullanmak convertbu sorunu önleyecektir.

'000000' yazmaktan kaçınmak için REPLICATE ('0', 6) 'yı çağırmak israftır ;-)
Mladen Mihajlovic

3
SELECT replicate('0', 6 - len(employeeID)) + convert(varchar, employeeID) as employeeID
FROM dbo.RequestItems 
WHERE ID=0

2
SELECT 
    cast(replace(str(EmployeeID,6),' ','0')as char(6)) 
FROM dbo.RequestItems
WHERE ID=0

Whoops. Aslında, bunu 7135.0verdiğimde bana verdi 7135.
jp2code

1

Çözüm, tüm Sql sürümleri için başında sıfır bulunan işaretli / negatif sayılar için çalışır:

DECLARE
    @n money = -3,
    @length tinyint = 15,
    @decimals tinyint = 0

SELECT REPLICATE('-', CHARINDEX('-', @n, 1)) + REPLACE(REPLACE(str(@n, @length, @decimals), '-', ''), ' ', '0')

1

En basit olan her zaman en iyisidir:

Select EmployeeID*1 as EmployeeID 

-1

Benim SQL sürümümde REPLICATE kullanamıyorum. Bu yüzden bunu yaptım:

SELECT 
    CONCAT(REPEAT('0', 6-LENGTH(emplyeeID)), emplyeeID) AS emplyeeID 
FROM 
    dbo.RequestItems`
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.