การจัดรูปแบบตัวเลขโดยการเติมด้วยศูนย์นำหน้าใน SQL Server


119

เรามีตาราง SQL เก่าที่ SQL Server 2000 ใช้เป็นเวลาเกือบ 10 ปี

ในนั้นหมายเลขบัตรพนักงานของเราจะถูกเก็บเป็นchar(6)จากไป000001999999

ตอนนี้ฉันกำลังเขียนเว็บแอปพลิเคชันและต้องการจัดเก็บหมายเลขตราพนักงาน

ในตารางใหม่ของฉันฉันอาจจะใช้ตัดสั้นและคัดลอกตารางเก่า แต่ฉันหวังสำหรับการถ่ายโอนข้อมูลที่ดีกว่า, ขนาดที่เล็กกว่า ฯลฯ โดยเพียงแค่การจัดเก็บintค่าจากการ1999999

ใน C # ฉันสามารถจัดรูปแบบintค่าสำหรับหมายเลขตราได้อย่างรวดเร็วโดยใช้

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

ฉันจะแก้ไขแบบสอบถาม SQL แบบธรรมดานี้เพื่อจัดรูปแบบค่าที่ส่งคืนด้วยได้อย่างไร

SELECT EmployeeID
FROM dbo.RequestItems
WHERE ID=0

ถ้าEmployeeIDเป็น 7135, 007135แบบสอบถามนี้ควรกลับ


ตั้งแต่ชั้นนำ0s มีความสำคัญต่อข้อมูลนี้ทำไมเปลี่ยนไปยังINTที่ทั้งหมดหรือไม่
Oded

2
SQL Server 2012 จะในที่สุดก็มีFORMATฟังก์ชั่นเช่น C # :-)
marc_s

1
@Oden: intค่านี้ใช้พื้นที่น้อยลงอย่างมากchar(6)และจะมีรายการเหล่านี้หลายรายการต่อชิ้นส่วนที่ผลิตขึ้น อย่างมีประสิทธิภาพ
jp2code

คุณกำลังเพิ่มประสิทธิภาพก่อนที่คุณจะประสบปัญหาหรือไม่?
Oded

4
มาดูกันว่าคุณมีหมายเลขตรามากถึงหนึ่งล้านหมายเลขและคุณคิดว่าคุณสามารถบันทึก (ตามDATALENGTH()) ได้สองไบต์ เนื่องจากคอลัมน์อาจอยู่ในดัชนีคุณจึงประหยัดได้มากกว่า 2MB และเมื่อเพิ่มคอลัมน์อื่นเข้าไป 2 ไบต์นั้นอาจเพียงพอที่จะลดความยาวของแถวให้เพียงพอที่จะบันทึกหน้า 4KB ต่อแถว สิ่งนี้จะโฮสต์บนแพลตฟอร์มมือถือหรือคุณอาจมุ่งความสนใจไปที่พื้นที่ที่ไม่ก่อให้เกิดประโยชน์?
HABO

คำตอบ:


172

เปลี่ยนตัวเลข 6 เป็นความยาวทั้งหมดของคุณ:

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

ถ้าคอลัมน์เป็น INT คุณสามารถใช้ RTRIM เพื่อแปลงเป็น VARCHAR โดยปริยาย

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

และรหัสเพื่อลบ 0 เหล่านี้และรับกลับหมายเลข 'จริง':

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

1
+1 คุณแสดงวิธีลบ 0 ให้ฉันด้วย! ให้ฉันทดสอบนี้และฉันจะทำเครื่องหมายเป็นคำตอบ
jp2code

1
คุณไม่จำเป็นต้องใช้รหัสเพื่อลบศูนย์เพียงแค่กำหนดหรือแปลงเป็น int และรหัสเหล่านั้นจะถูกลบโดยอัตโนมัติ
Jimbo

2
ใช้งานได้ก็ต่อเมื่อค่าที่ส่งผ่านเป็นสตริงหากคุณส่งจำนวนเต็มคุณจะได้ค่าเดียวกับที่คุณส่งผ่าน
Mordy

2
แม้ว่าจะเก่าแล้ว ... การใช้ "+ convert (varchar, EmployeeID)" แทน "+ EmployeeID" ควรแก้ปัญหา int
Krishna Sarma

3
เป็นวิธีที่ดีเว้นแต่ EmployeeId จะมากกว่า 6 หลักซึ่งทำให้เกิดผลลัพธ์ที่เป็นโมฆะ ฟังก์ชั่นการติดต่อคือคำตอบ: SELECT CONCAT (REPLICATE ('0', 6-LEN (CONVERT (varchar, EmployeeId))), EmployeeId)
Mahmoud Moravej

125

เพียงใช้ฟังก์ชัน FORMAT (ทำงานบน SQL Server 2012 หรือใหม่กว่า):

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

อ้างอิง: http://msdn.microsoft.com/en-us/library/hh213505.aspx


1
นี่เป็นคำถามเก่าก่อนที่ SQL Server 2012 จะออกมา
jp2code

19
ถึงกระนั้นฉันก็อยากเห็นฟองสบู่นี้ใกล้ด้านบนมากขึ้น
Dave Haynes

4
ในกรณีที่มีใครสงสัย Formatไม่สงวนชนิดข้อมูล แต่แปลงเป็น nvarchar โดยปริยาย:select sql_variant_property(50, 'BaseType'), sql_variant_property(format(50, N'00000'), 'BaseType')
Ralph

2
วิธีนี้เป็นวิธีที่ง่ายที่สุดและ IMHO เป็นทางออกที่ดีที่สุด
Robert Lujo

ระวังฟังก์ชั่นนี้หากคุณใช้มันสำหรับชุดข้อมูลขนาดใหญ่
amd

33

คุณสามารถเปลี่ยนขั้นตอนของคุณได้ด้วยวิธีนี้

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

อย่างไรก็ตามสิ่งนี้ถือว่าคุณEmployeeIDเป็นค่าตัวเลขและรหัสนี้เปลี่ยนผลลัพธ์เป็นสตริงฉันขอแนะนำให้เพิ่มค่าตัวเลขเดิมอีกครั้ง

แก้ไขแน่นอนฉันไม่ได้อ่านคำถามด้านบนอย่างละเอียด มันบอกว่าช่องนั้นเป็นchar(6)EmployeeID ไม่ใช่ค่าตัวเลข แม้ว่าคำตอบนี้จะยังคงมีค่าต่อตัว แต่ก็ไม่ใช่คำตอบที่ถูกต้องสำหรับคำถามข้างต้น


นี่เป็นวิธีที่สะอาดที่สุดที่ฉันคิด ขอบคุณ
iheartcsharp

นั่นคือ'000000'สิ่งที่จำเป็นจริงๆ .. ? '0'ยังทำงานได้ดี ปลอดภัยไหมถ้าใช้ 0 อันเดียว .. ?
shashwat

1
OP ขอสตริงความยาว 6 ตัวอักษรเป็นผลลัพธ์ โดยเฉพาะถ้าเป็น EmployeeID 7135, แบบสอบถามนี้ควรกลับ 007135 ใช้เพียงหนึ่ง '0' ผลตอบแทนไม่ได้07135 007135แนวคิดทั้งหมดคือการเชื่อมต่อกับสตริง 6 อักขระที่ประกอบด้วยสตริงทั้งหมด0ที่แปลง EmployeedID จากนั้นเริ่มจากขอบด้านขวาใช้ 6 ตัวอักษร ไม่ว่าความยาวใดก็ตาม ID คือวิธีการด้านบนจะส่งกลับสตริงที่มีเพียงจำนวนศูนย์ถ่านที่ต้องการเพื่อให้ถึงความยาว 6 อักขระ
สตีฟ

อาจเป็นเลขศูนย์ 5 ตัว'00000'เนื่องจากEmployeeIDจะมีตัวเลขอย่างน้อยหนึ่งหลัก แต่REPLICATE()ฟังก์ชั่นดูเหมือนจะพอดีกว่าเช่นในคำตอบอื่น ๆ
nosklo

26

เกลียดที่ต้องแปลง int และดูเหมือนว่าจะง่ายกว่ามาก อาจทำงานได้ดีขึ้นเนื่องจากมีการแปลงสตริงเพียงครั้งเดียวและการเพิ่มอย่างง่าย

เลือกRIGHT (1000000 + EmployeeId, 6) ...

ตรวจสอบให้แน่ใจว่า "1000000" มีเลขศูนย์อย่างน้อยที่สุดเท่าที่จำเป็น


11

ฉันกำลังโพสต์ทั้งหมดในที่เดียวทุกอย่างใช้ได้กับฉันเพื่อรองด้วย 4 ศูนย์นำหน้า :)

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')

ซึ่งครอบคลุมตัวเลือกที่จำเป็นทั้งหมด ขอบคุณ.
kyurthich

6

อีกวิธีหนึ่งเพียงเพื่อความสมบูรณ์

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

หรือตามคำถามของคุณ

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

@ jp2code - คุณต้องอ่านว่า StackOverflow คืออะไร - แก้ไขร่วมกันเช่น wiki ไม่ใช่คำถามของคุณทันทีที่คุณโพสต์! สิ่งที่มักจะถูกแก้ไขออกมามักจะเป็น "ปุย" มากเกินไปเช่นการขอบคุณล่วงหน้าและการใช้ไวยากรณ์ / ตัวพิมพ์ใหญ่ไม่ดี
Jamiec


4

สะอาดที่สุดเท่าที่จะทำได้และให้ขอบเขตของการแทนที่ด้วยตัวแปร:

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

ถ้าEmployeeIDคอลัมน์ถูกกำหนดเป็นintตัวดำเนินการ + จะถือว่าเป็นการเพิ่มแทนที่จะเป็นการเรียงต่อกันดังนั้นเลขศูนย์จะหายไป การใช้convertจะหลีกเลี่ยงปัญหานี้

การเรียก REPLICATE ('0', 6) เพื่อหลีกเลี่ยงการพิมพ์ '000000' เป็นการสิ้นเปลือง ;-)
Mladen Mihajlovic



1

โซลูชันนี้ใช้ได้กับตัวเลขที่ลงชื่อ / ลบด้วยศูนย์นำหน้าสำหรับ Sql ทุกเวอร์ชัน

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

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


-1

ใน SQL เวอร์ชันของฉันฉันไม่สามารถใช้ REPLICATE ได้ ฉันจึงทำสิ่งนี้:

SELECT 
    CONCAT(REPEAT('0', 6-LENGTH(emplyeeID)), emplyeeID) AS emplyeeID 
FROM 
    dbo.RequestItems`
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.