Formatieren von Zahlen durch Auffüllen mit führenden Nullen in SQL Server

119

Wir haben eine alte SQL-Tabelle, die fast 10 Jahre lang von SQL Server 2000 verwendet wurde.

Darin werden unsere Mitarbeiterausweisnummern char(6)von 000001bis gespeichert 999999.

Ich schreibe gerade eine Webanwendung und muss die Ausweisnummern der Mitarbeiter speichern.

In meiner neuen Tabelle könnte ich die Verknüpfung nehmen und die alte Tabelle kopieren, aber ich hoffe auf eine bessere Datenübertragung, kleinere Größe usw., indem ich einfach die intWerte von 1bis speichere 999999.

In C # kann ich mit schnell einen intWert für die Ausweisnummer formatieren

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

Wie würde ich diese einfache SQL-Abfrage ändern, um auch den zurückgegebenen Wert zu formatieren?

SELECT EmployeeID
FROM dbo.RequestItems
WHERE ID=0

Wenn EmployeeID7135 ist, sollte diese Abfrage zurückgegeben werden 007135.

jp2code
quelle
Da führende 0s für dieses Gebiet von Bedeutung sind, warum sollte man sie überhaupt in ein ändern INT?
Oded
2
SQL Server 2012 wird endlich eine FORMATFunktion wie C # haben :-)
marc_s
1
@Oden: Die intWerte nehmen deutlich weniger Platz ein char(6), und es werden mehrere dieser Einträge pro Teil hergestellt, das hergestellt wird. Effizienz.
jp2code
Optimieren Sie, bevor ein Problem auftritt?
Oded
4
Mal sehen, Sie haben bis zu eine Million Ausweisnummern und Sie rechnen damit, dass Sie (nach DATALENGTH()) jeweils zwei Bytes speichern können. Da sich die Spalte möglicherweise in einem Index befindet, können Sie mehr als 2 MB speichern. Und wenn andere Spalten addiert werden, reichen diese 2 Bytes möglicherweise gerade aus, um die Länge einer Zeile so weit zu reduzieren, dass eine 4-KB-Seite pro Zeile gespeichert wird. Wird dies auf einer mobilen Plattform gehostet oder konzentrieren Sie Ihre Aufmerksamkeit möglicherweise auf einen unproduktiven Bereich?
HABO

Antworten:

172

Ändern Sie die Zahl 6 in die Gesamtlänge, die Sie benötigen:

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

Wenn die Spalte eine INT ist, können Sie sie mit RTRIM implizit in eine VARCHAR konvertieren

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

Und der Code, um diese Nullen zu entfernen und die 'echte' Zahl zurückzugewinnen:

SELECT RIGHT(EmployeeId,(LEN(EmployeeId) - PATINDEX('%[^0]%',EmployeeId)) + 1)
Vince Pergolizzi
quelle
1
+1 Du hast mir sogar gezeigt, wie man die Nullen entfernt! Lassen Sie mich das testen und ich werde es als Antwort markieren.
jp2code
Sie benötigen keinen Code, um die Nullen zu entfernen. Weisen Sie sie einfach zu oder konvertieren Sie sie in ein Int. Sie werden automatisch entfernt.
Jimbo
2
Dies funktioniert nur, wenn der übergebene Wert eine Zeichenfolge ist. Wenn Sie eine Ganzzahl übergeben, erhalten Sie den gleichen Wert, den Sie übergeben haben.
Mordy
2
Obwohl seine alte ... Verwendung von "+ convert (varchar, EmployeeID)" anstelle von "+ EmployeeID" das int-Problem lösen sollte
Krishna Sarma
3
Dies ist ein guter Weg, es sei denn, die EmployeeId ist größer als 6 Stellen, was zu einem NULL-Ergebnis führt. Die Kontaktfunktion ist die Antwort: SELECT CONCAT (REPLICATE ('0', 6-LEN (CONVERT (varchar, EmployeeId))), EmployeeId)
Mahmoud Moravej
125

Verwenden Sie einfach die FORMAT-Funktion (funktioniert unter SQL Server 2012 oder neuer):

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

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

EdMorte
quelle
1
Dies ist eine alte Frage - bevor SQL Server 2012 herauskam.
jp2code
19
Trotzdem würde ich diese Blase jetzt gerne etwas näher an der Spitze sehen.
Dave Haynes
4
Nur für den Fall, dass sich jemand wundert. Formatbehält den Datentyp nicht bei, konvertiert aber implizit in nvarchar:select sql_variant_property(50, 'BaseType'), sql_variant_property(format(50, N'00000'), 'BaseType')
Ralph
2
Dieser Weg ist die einfachste und meiner Meinung nach die beste Lösung.
Robert Lujo
amd
33

Sie können Ihr Verfahren auf diese Weise ändern

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

Dies setzt jedoch voraus, dass Ihr EmployeeIDWert ein numerischer Wert ist und dieser Code das Ergebnis in eine Zeichenfolge ändert. Ich empfehle, den ursprünglichen numerischen Wert erneut hinzuzufügen

BEARBEITEN Natürlich habe ich die obige Frage nicht sorgfältig gelesen. Es heißt, dass das Feld eine char(6)so ist, dass EmployeeID kein numerischer Wert ist. Obwohl diese Antwort per se immer noch einen Wert hat, ist sie nicht die richtige Antwort auf die obige Frage.

Steve
quelle
Dies ist meiner Meinung nach der sauberste Weg, dies zu tun. Danke
iheartcsharp
Ist das '000000'wirklich notwendig ..? '0'funktioniert auch gut. Ist es sicher, nur eine 0 zu verwenden?
Shashwat
1
Das OP forderte als Ergebnis eine Zeichenfolge mit einer Länge von 6 Zeichen an. Insbesondere wenn EmployeeID 7135 ist, sollte diese Abfrage 007135 zurückgeben . Die Verwendung von nur einer '0' gibt 07135nicht zurück 007135. Die ganze Idee besteht darin, eine Zeichenfolge 0mit 6 Zeichen zu verketten, die aus der gesamten konvertierten EmployeedID besteht, und dann ab dem rechten Rand 6 Zeichen zu verwenden. Unabhängig von der Länge der ID gibt die oben beschriebene Methode immer eine Zeichenfolge mit nur der Anzahl von Null Zeichen zurück, die erforderlich ist, um die Länge von 6 Zeichen zu erreichen
Steve
Es können 5 Nullen sein, '00000'da die EmployeeIDmindestens eine Ziffer enthalten. Aber die REPLICATE()Funktion scheint passender zu sein, wie in den anderen Antworten
nosklo
26

Ich hasste es, das Int konvertieren zu müssen, und das scheint viel einfacher zu sein. Könnte sogar eine bessere Leistung erzielen, da es nur eine Zeichenfolgenkonvertierung und eine einfache Addition gibt.

Wählen Sie RECHTS (1000000 + EmployeeId, 6) ...

Stellen Sie einfach sicher, dass der "1000000" mindestens so viele Nullen wie die benötigte Größe hat.

JeffSahol
quelle
11

Ich poste alles an einem Ort, alles funktioniert für mich, um mit 4 führenden Nullen aufzufüllen :)

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')
Raj Kumar
quelle
Dies umfasst alle erforderlichen Optionen. Danke dir.
Kyurthich
6

Ein anderer Weg, nur der Vollständigkeit halber.

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

Oder gemäß Ihrer Anfrage

SELECT STUFF('000000', 6-LEN(EmployeeID)+1, LEN(EmployeeID), EmployeeID) 
         AS EmployeeCode
FROM dbo.RequestItems
WHERE ID=0
Jamiec
quelle
@ jp2code - Sie müssen nachlesen, was StackOverflow ist - es wird gemeinsam wie ein Wiki bearbeitet - es ist nicht Ihre Frage, sobald Sie es veröffentlicht haben! Dinge, die häufig herausgeschnitten werden, sind übermäßige "Flusen" wie das Danken im Voraus und schlechte Grammatik / Großschreibung.
Jamiec
5

Ab Version 2012 können Sie verwenden

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

So sauber wie es nur geht und den Umfang des Ersetzens durch Variablen bietet:

Select RIGHT(REPLICATE('0',6) + EmployeeID, 6) from dbo.RequestItems
WHERE ID=0
Divanshu
quelle
Wenn die EmployeeIDSpalte als definiert intist, wird der Operator + eher als Addition als als Verkettung behandelt, sodass die Nullen verloren gehen. Durch convertdie Verwendung wird dieses Problem vermieden.
Das Aufrufen von REPLICATE ('0', 6), um die Eingabe von '000000' zu vermeiden, ist nur verschwenderisch ;-)
Mladen Mihajlovic
3
SELECT replicate('0', 6 - len(employeeID)) + convert(varchar, employeeID) as employeeID
FROM dbo.RequestItems 
WHERE ID=0
Jimbo
quelle
2
SELECT 
    cast(replace(str(EmployeeID,6),' ','0')as char(6)) 
FROM dbo.RequestItems
WHERE ID=0
user1227804
quelle
Hoppla. Eigentlich gab mir das, 7135.0als ich es gab 7135.
jp2code
1

Die Lösung funktioniert für vorzeichenbehaftete / negative Zahlen mit führenden Nullen für alle SQL-Versionen:

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

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

Das Einfachste ist immer das Beste:

Select EmployeeID*1 as EmployeeID 
Michal
quelle
-1

In meiner SQL-Version kann ich REPLICATE nicht verwenden. Also habe ich das gemacht:

SELECT 
    CONCAT(REPEAT('0', 6-LENGTH(emplyeeID)), emplyeeID) AS emplyeeID 
FROM 
    dbo.RequestItems`
Zlato010
quelle