เราจำเป็นต้องทำการรายงานบางอย่างเกี่ยวกับค่าที่มักจะรวมสตริงของตัวเลขและตัวอักษรที่ต้องเรียงลำดับ 'ตามธรรมชาติ' สิ่งที่ต้องการเช่น "P7B18" หรือ "P12B3" @ สายอักขระส่วนใหญ่จะเป็นลำดับของตัวอักษรจากนั้นจึงสลับตัวเลข จำนวนของกลุ่มเหล่านี้และความยาวของแต่ละกลุ่มอาจแตกต่างกันไป
เราต้องการเรียงลำดับตัวเลขเหล่านี้ตามลำดับตัวเลข เห็นได้ชัดว่าถ้าฉันจัดการค่าสตริงเหล่านั้นโดยตรงด้วยORDER BY
"P12B3" จะมาก่อน "P7B18" เนื่องจาก "P1" เก่ากว่า "P7" แต่ฉันต้องการย้อนกลับเพราะ "P7" อยู่ก่อน "P12"
ฉันยังต้องการที่จะทำการเปรียบเทียบช่วงเช่น@bin < 'P13S6'
หรือบางอย่างเช่น ฉันไม่ต้องจัดการกับจำนวนจุดลอยตัวหรือจำนวนลบ; สิ่งเหล่านี้จะเป็นจำนวนเต็มที่ไม่ติดลบที่เรากำลังทำอยู่ ความยาวสตริงและจำนวนของเซกเมนต์อาจเป็นไปได้เองโดยไม่ จำกัด ขอบเขต
ในกรณีของเราปลอกสตริงนั้นไม่สำคัญแม้ว่าจะมีวิธีการในการเปรียบเทียบการเรียงตัว แต่คนอื่น ๆ อาจพบว่ามีประโยชน์ ส่วนที่น่าเกลียดที่สุดของทั้งหมดนี้คือฉันต้องการที่จะทำทั้งการสั่งซื้อและการกรองช่วงในWHERE
ข้อ
ถ้าฉันทำสิ่งนี้ใน C # มันจะเป็นงานที่ค่อนข้างง่าย: ทำการแยกวิเคราะห์เพื่อแยกอัลฟาจากตัวเลขใช้ IComparable และคุณก็ทำได้โดยทั่วไป แน่นอนว่า SQL Server ไม่ได้เสนอฟังก์ชั่นที่คล้ายกันอย่างน้อยที่สุดเท่าที่ฉันทราบ
ใครรู้เทคนิคที่ดีในการทำงานนี้หรือไม่? มีความสามารถเล็กน้อยเผยแพร่ในการสร้างประเภท CLR ที่กำหนดเองที่ใช้ IComparable และมีพฤติกรรมนี้ตามที่คาดไว้? ฉันยังไม่ได้คัดค้าน Stupid XML Tricks (ดูเพิ่มเติมที่: การต่อข้อมูลรายการ) และฉันมี CLR regex การจับคู่ / การแยก / การแยก / การแทนที่ฟังก์ชั่น wrapper ที่มีอยู่บนเซิร์ฟเวอร์เช่นกัน
แก้ไข: ตามตัวอย่างที่ละเอียดกว่าเล็กน้อยฉันต้องการให้ข้อมูลทำอะไรแบบนี้
SELECT bin FROM bins ORDER BY bin
bin
--------------------
M7R16L
P8RF6JJ
P16B5
PR7S19
PR7S19L
S2F3
S12F0
ie แบ่งสตริงเป็นโทเค็นของตัวอักษรทั้งหมดหรือตัวเลขทั้งหมดและเรียงลำดับตามลำดับตัวอักษรหรือตัวเลขตามลำดับโดยโทเค็นซ้ายสุดเป็นคำที่เรียงลำดับที่สำคัญที่สุด อย่างที่ฉันบอกไปแล้วว่าชิ้นส่วนของเค้กใน. NET ถ้าคุณใช้ IComparable แต่ฉันไม่รู้ว่าคุณสามารถทำสิ่งนั้นใน SQL Server ได้อย่างไร (หรือถ้า) แน่นอนว่าไม่ใช่สิ่งที่ฉันเคยเจอมาใน 10 ปีหรือมากกว่านั้นด้วยการทำงานกับมัน
P7B12
อาจกลายเป็นP 07 B 12
แล้ว (ผ่าน ASCII)80 07 65 12
ดังนั้น80076512