การใช้ REVERSE
, CHARINDEX
และ SUBSTRING
อย่างเหมาะสมจะทำให้เราได้สิ่งที่เราต้องการ ฉันได้ใช้ชื่อคอลัมน์ที่หวังว่าจะอธิบายได้ในโค้ดด้านล่างเพื่อแสดงให้เห็นว่าเกิดอะไรขึ้น
ตั้งค่าข้อมูลตัวอย่าง:
DECLARE @Invoice TABLE (
InvoiceNumber nvarchar(10)
);
INSERT @Invoice VALUES
('790711')
,('790709-1')
,('790709-11')
,('790709-21')
,('790709-212')
,('790709-2')
SELECT * FROM @Invoice
ข้อมูลตัวอย่าง:
InvoiceNumber
-------------
790711
790709-1
790709-11
790709-21
790709-212
790709-2
และนี่คือรหัส ฉันรู้สึกจู้จี้จุกจิกที่สำนวนสุดท้ายสามารถทำให้ง่ายขึ้นได้
SELECT
InvoiceNumber
,REVERSE(InvoiceNumber)
AS Reversed
,CHARINDEX('-',REVERSE(InvoiceNumber))
AS HyphenIndexWithinReversed
,SUBSTRING(REVERSE(InvoiceNumber),1+CHARINDEX('-',REVERSE(InvoiceNumber)),LEN(InvoiceNumber))
AS ReversedWithoutAffix
,SUBSTRING(InvoiceNumber,1+LEN(SUBSTRING(REVERSE(InvoiceNumber),1+CHARINDEX('-',REVERSE(InvoiceNumber)),LEN(InvoiceNumber))),LEN(InvoiceNumber))
AS AffixIncludingHyphen
,SUBSTRING(InvoiceNumber,2+LEN(SUBSTRING(REVERSE(InvoiceNumber),1+CHARINDEX('-',REVERSE(InvoiceNumber)),LEN(InvoiceNumber))),LEN(InvoiceNumber))
AS AffixExcludingHyphen
,CAST(
SUBSTRING(InvoiceNumber,2+LEN(SUBSTRING(REVERSE(InvoiceNumber),1+CHARINDEX('-',REVERSE(InvoiceNumber)),LEN(InvoiceNumber))),LEN(InvoiceNumber))
AS int)
AS AffixAsInt
,REVERSE(SUBSTRING(REVERSE(InvoiceNumber),1+CHARINDEX('-',REVERSE(InvoiceNumber)),LEN(InvoiceNumber)))
AS WithoutAffix
FROM @Invoice
ORDER BY
-- WithoutAffix
REVERSE(SUBSTRING(REVERSE(InvoiceNumber),1+CHARINDEX('-',REVERSE(InvoiceNumber)),LEN(InvoiceNumber)))
-- AffixAsInt
,CAST(
SUBSTRING(InvoiceNumber,2+LEN(SUBSTRING(REVERSE(InvoiceNumber),1+CHARINDEX('-',REVERSE(InvoiceNumber)),LEN(InvoiceNumber))),LEN(InvoiceNumber))
AS int)
เอาท์พุท:
InvoiceNumber Reversed HyphenIndexWithinReversed ReversedWithoutAffix AffixIncludingHyphen AffixExcludingHyphen AffixAsInt WithoutAffix
------------- ---------- ------------------------- -------------------- -------------------- -------------------- ----------- ------------
790709-1 1-907097 2 907097 -1 1 1 790709
790709-2 2-907097 2 907097 -2 2 2 790709
790709-11 11-907097 3 907097 -11 11 11 790709
790709-21 12-907097 3 907097 -21 21 21 790709
790709-212 212-907097 4 907097 -212 212 212 790709
790711 117097 0 117097 0 790711
โปรดทราบว่าสิ่งที่คุณต้องการจริงๆ คือส่วนคำสั่ง ORDER BY
ที่เหลือเพียงเพื่อแสดงการทำงานของฉัน ซึ่งมีลักษณะดังนี้:
- ย้อนกลับสตริง, ค้นหายัติภังค์, รับสตริงย่อยหลังยัติภังค์, ย้อนกลับส่วนนั้น: นี่คือตัวเลขโดยไม่ต้องต่อท้ายใดๆ
- ความยาวของ (ตัวเลขที่ไม่มีส่วนต่อท้าย) บอกเราว่าต้องทิ้งอักขระจำนวนเท่าใดตั้งแต่เริ่มต้น เพื่อให้ได้ส่วนต่อท้ายรวมทั้งเครื่องหมายยัติภังค์ด้วย วางอักขระเพิ่มเติมเพื่อให้ได้เฉพาะส่วนที่เป็นตัวเลข และแปลงเป็น
int
โชคดีที่เราได้รับการหยุดพักจาก SQL Server เนื่องจากการแปลงนี้ให้ค่าศูนย์สำหรับสตริงว่าง
- ในที่สุด เมื่อได้สองส่วนนี้มา เราก็สร้าง
ORDER BY
(ตัวเลขที่ไม่มีส่วนต่อท้าย) แล้วตามด้วย (ค่าตัวเลขของส่วนต่อท้าย) นี่คือคำสั่งสุดท้ายที่เราแสวงหา
โค้ดจะกระชับกว่านี้ถ้า SQL Server อนุญาตให้เราพูด SUBSTRING(value, start)
เพื่อให้สตริงเริ่มต้นที่จุดนั้น แต่ก็ไม่เป็นเช่นนั้น ดังนั้นเราจึงต้องพูด SUBSTRING(value, start, LEN(value))
บ่อยครั้ง
person
AakashM
schedule
06.06.2013