SQL สำหรับการเรียงลำดับตามหมายเลข - 1,2,3,4 ฯลฯ แทนที่จะเป็น 1,10,11,12


87

ฉันกำลังพยายามเรียงลำดับตามคอลัมน์ตัวเลขในฐานข้อมูลของฉันซึ่งมีค่า 1-999

เมื่อฉันใช้

ORDER_BY registration_no ASC

ฉันเข้าใจ….

1
101
102
103
104
105
106
107
108
109
11
110
Etc…

ดังนั้นจึงดูเหมือนว่าจะเรียงลำดับตามหลักแรกตรงข้ามกับหมายเลข

มีใครรู้บ้างว่าต้องใช้ SQL อะไรถ้าต้องการสั่งตามค่า? ดังนั้น1,2,3,4,5,6ฯลฯ


11
คอลัมน์ของคุณเป็นประเภท varchar เนื่องจากคุณกำลังเผชิญกับพฤติกรรมนี้
Meherzad

ประเภทข้อมูลของคอลัมน์ register_no คืออะไร?
ประวีณประสานนันท์

9
ใช้order by registration_no + 0 ascเพื่อแก้ปัญหาของคุณ
Meherzad

10
คุณไม่ควรเก็บตัวเลขไว้ในคอลัมน์อักขระ ปัญหาของคุณเป็นผลโดยตรงจากข้อผิดพลาดนั้น
a_horse_with_no_name

1
คอลัมน์ของฉันคือ Varchar และข้อมูลที่ฉันจัดเก็บคือคลาส 10 / คลาส 9 / คลาส 8 ตอนนี้คลาส 10 มาก่อนคลาส 8 ฉันจะแก้ปัญหานี้ได้อย่างไรโดยไม่ต้องทำในคอลัมน์ display_order
วิษณุรัฐ

คำตอบ:


142

วิธีหนึ่งในการเรียงลำดับโดยจำนวนเต็มบวกเมื่อจัดเก็บเป็นvarcharคือการเรียงลำดับตามความยาวก่อนแล้วจึงตามด้วยค่า:

order by len(registration_no), registration_no

สิ่งนี้มีประโยชน์อย่างยิ่งเมื่อคอลัมน์อาจมีค่าที่ไม่ใช่ตัวเลข

หมายเหตุ: ในฐานข้อมูลบางฟังก์ชั่นที่จะได้รับความยาวของสตริงที่อาจจะเรียกว่าแทนlength()len()


1
วิธีนี้จะใช้ไม่ได้ในทุกกรณี กรณีที่ไม่สามารถใช้งานได้คือการผสมของจำนวนเต็มด้วย; จำนวนลบตัวเลขที่มีเลขศูนย์นำหน้าตัวเลขที่มีเศษส่วนและคำและตัวเลขรวมกัน
WonderWorker

10
@ Knickerless-Noggins. . . อ่านประโยคแรกของคำตอบ ผมคิดว่ามันค่อนข้างชัดเจน
Gordon Linoff

@GordonLinoff กำลังเรียงลำดับตามคอลัมน์เดียวกันสองครั้งไม่ใช่ CPU และหน่วยความจำเข้มข้น
loneStar

@ อัคนี. . . จำนวนปุ่มในตัวorder byมีผลเพียงเล็กน้อยต่อประสิทธิภาพการทำงาน
Gordon Linoff

1
สำหรับ Oracle SQL ให้ใช้length()แทนlen()
Stevoisiak

62
ORDER_BY cast(registration_no as unsigned) ASC

แปลงค่าเป็นตัวเลขอย่างชัดเจน ความเป็นไปได้อีกประการหนึ่งที่จะบรรลุเป้าหมายเดียวกันก็คือ

ORDER_BY registration_no + 0 ASC

ซึ่งจะบังคับให้มีการสนทนาโดยปริยาย

จริงๆแล้วคุณควรตรวจสอบนิยามตารางและเปลี่ยน คุณสามารถเปลี่ยนประเภทข้อมูลเป็นintแบบนี้ได้

ALTER TABLE your_table MODIFY COLUMN registration_no int;


4
ORDER_BY cast(registration_no as unsigned) ASC

ให้ผลลัพธ์ที่ต้องการพร้อมคำเตือน

ดังนั้นดีกว่าที่จะไป

ORDER_BY registration_no + 0 ASC

เพื่อผลลัพธ์ที่สะอาดโดยไม่มีคำเตือน SQL


คุณอธิบาย+ 0ได้ไหมว่าทำไมต้องทำผลงาน ฉันได้ทดสอบกับชุดข้อมูลของฉันแล้วและใช้งานได้จริง แต่ฉันสงสัยว่าทำไม? มันแปลงเป็นตัวเลขก่อนสั่งซื้อหรือไม่?
Joshua Pinter

2

ฉันถือว่าประเภทคอลัมน์ของคุณคือ STRING (CHAR, VARCHAR ฯลฯ ) และขั้นตอนการเรียงลำดับกำลังจัดเรียงเป็นสตริง สิ่งที่คุณต้องทำคือการแปลงค่าเป็นค่าตัวเลข วิธีการทำจะขึ้นอยู่กับระบบ SQL ที่คุณใช้


1

บางครั้งคุณก็ไม่มีทางเลือกว่าจะต้องเก็บตัวเลขผสมกับข้อความ หนึ่งในแอปพลิเคชันของเราโฮสต์เว็บไซต์ที่เราใช้สำหรับไซต์อีคอมเมิร์ซของเราจะสร้างตัวกรองออกจากรายการแบบไดนามิก ไม่มีตัวเลือกในการจัดเรียงตามเขตข้อมูลใด ๆ นอกจากข้อความที่แสดง เมื่อเราต้องการตัวกรองที่สร้างขึ้นจากรายการที่กล่าวถึงสิ่งต่างๆเช่น 2 "ถึง 8" 9 "ถึง 12" 13 "ถึง 15" เป็นต้นเราต้องการให้ตัวกรองนี้เรียงลำดับ 2-9-13 ไม่ใช่ 13-2-9 ตามที่จะทำเมื่อ การอ่านค่าตัวเลข ดังนั้นฉันจึงใช้ฟังก์ชัน SQL Server Replicate พร้อมกับความยาวของตัวเลขที่ยาวที่สุดเพื่อรองตัวเลขที่สั้นกว่าด้วยช่องว่างนำหน้า ตอนนี้ 20 เรียงลำดับหลัง 3 ไปเรื่อย ๆ

ฉันกำลังทำงานกับมุมมองที่ให้ความยาวต่ำสุดและสูงสุดความกว้าง ฯลฯ สำหรับประเภทรายการและคลาสและนี่คือตัวอย่างของวิธีที่ฉันทำข้อความ (LB nต่ำและ LB nสูงคือปลายต่ำและสูงของวงเล็บ 5 ตัว)

REPLICATE(' ', LEN(LB5Low) - LEN(LB1High)) + CONVERT(NVARCHAR(4), LB1High) + '" and Under' AS L1Text,
REPLICATE(' ', LEN(LB5Low) - LEN(LB2Low)) + CONVERT(NVARCHAR(4), LB2Low) + '" to ' + CONVERT(NVARCHAR(4), LB2High) + '"' AS L2Text,
REPLICATE(' ', LEN(LB5Low) - LEN(LB3Low)) + CONVERT(NVARCHAR(4), LB3Low) + '" to ' + CONVERT(NVARCHAR(4), LB3High) + '"' AS L3Text,
REPLICATE(' ', LEN(LB5Low) - LEN(LB4Low)) + CONVERT(NVARCHAR(4), LB4Low) + '" to ' + CONVERT(NVARCHAR(4), LB4High) + '"' AS L4Text,
CONVERT(NVARCHAR(4), LB5Low) + '" and Over' AS L5Text

1

ฉันชอบทำ "PAD" กับข้อมูลมากกว่า MySql เรียกมันว่า LPAD แต่คุณสามารถทำสิ่งเดียวกันใน SQL Server ได้

ORDER BY  REPLACE(STR(ColName, 3), SPACE(1), '0') 

สูตรนี้จะให้ค่าศูนย์นำหน้าตามความยาวของคอลัมน์ที่ 3 ฟังก์ชันนี้มีประโยชน์มากในสถานการณ์อื่น ๆ นอกเหนือจาก ORDER BY ดังนั้นฉันจึงต้องการให้ตัวเลือกนี้

ผลลัพธ์: 1 กลายเป็น 001 และ 10 กลายเป็น 010 ในขณะที่ 100 ยังคงเหมือนเดิม


0

ปัญหานี้เป็นเพียงเพราะคุณได้ประกาศคอลัมน์ในประเภทข้อมูล CHAR, VARCHAR หรือ TEXT เพียงแค่เปลี่ยนประเภทข้อมูลเป็น INT, BIGINT เป็นต้นวิธีนี้จะช่วยแก้ปัญหาการสั่งซื้อที่คุณกำหนดเองได้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.