บทความนี้เกิดจากผมช่วยแก้ปัญหา การเรียงลำดับข้อมูลให้เพื่อนท่านหนึ่งทาง msn โดยมีข้อตกลงว่า เขาจะต้องเขียนบทความอธิบายสิ่งที่ผมช่วยไป ส่งผม จึงเป็นที่มาของบทความนี้ เราไปดูกันว่าอะไรเกิดขึ้น อ่านบทความนี้ในรูปแบบเอกสารเวิร์ด
บทความโดย : buarapa[at]hotmail.com
ขอขอบคุณน้ำใจอันงาม ที่ยอมให้เอาบทความมาเผยแพร่

หลายท่านสงสัยกับการเรียงลำดับที่ถูกต้องของตัวหนังสือต้องเรียงจาก ก-ฮ,A-Z หรือตัวเลขต้อง1 2 3 … ∞ ว่าแต่มันก็เรียงอยู่แล้วนิ แต่การเรียงลำดับที่เก็บเป็นชนิดฟิลด์เป็นตัวหนังสือ มันเรียงลำดับถูกของมัน แต่ไม่ถูกของเรา มาดูกันครับ

เรามีข้อมูลอยู่ในฟิลด์ id(int), idk(varchar), name(varchar) ชื่อตารางว่า money ข้อมูลในตารางมีดังนี้

ididkName
11/2551100
22/2551366
310/2551362

ในการจัดเรียงลำดับจากน้อยไปมากโดยใช้ idk จะได้

ididkName
310/2551362
11/2551100
22/2551366

พอเราจัดเรียงจากมากไปน้อยโดยใช้ idk ในการจัดเรียงเช่นกันเราได้

ididkName
22/2551366
11/2551100
310/2551362

แล้วทำไมเรียงลำดับน้อยไปมากมันได้ 10/2551 ออกมาก่อน แล้วมากไปน้อยมันได้ 2/2551 มันก็ดันออกมาก่อนอีก นึกได้ว่ามันเป็นฟิลด์ตัวหนังสือมันเลยแสดงออกมาตามที่เราคิดไม่ได้ สิ่งที่เราคิดไว้ต้องทำยังไงผมลองค้นแล้วสรุปได้ว่า ฟังก์ชั่น CAST( string AS type) ช่วยให้สิ่งที่แสดงตรงกับความคิดเราได้ ขอยกตัวอย่างแล้วอธิบายภายหลังละกันครับ

SUBSTRING_INDEX คือคำสั่งที่ใช้แยกตัวหนังสือออกมากเป็นสิ่งที่เราต้องการ SUBSTRING_INDEX(ฟิลด์, 'เครื่องหมาย',ลำดับ)
 
SIGNED ตัวเลขที่ได้สามารถติดลบได้
 
UNSIGNED ตัวเลขที่ได้ไม่ติดลบ

ตัวอย่าง

$query_money = "SELECT *, CAST( SUBSTRING_INDEX(money.idk,'/',1) AS UNSIGNED ) AS d, CAST( SUBSTRING_INDEX(money.idk,'/',-1) AS UNSIGNED ) AS y FROM money ORDER BY y DESC , d DESC";

อธิบาย

CAST( SUBSTRING_INDEX(money.idk,'/',1) AS UNSIGNED ) AS d

คำสั่งนี้ความหมายว่า ให้เอาตัวหนังสือจากฟิลด์ money.idk ที่แยกโดยใช้เครื่องหมาย / ชุดที่ 1(นับจากซ้าย)มาแปลงให้เป็นตัวเลข แล้วเก็บไว้ในฟิลด์ชั่วคราวที่ชื่อ d เพื่อเราจะได้เอามันไป order by ในการจัดเรียงลำดับต่อไป

เลข1ในโค๊ดหมายถึงลำดับที่1 นับจากซ้ายไปขวาเช่น ถ้าข้อมูลเราเก็บไว้ 1/2551 เป็นตัวหนังสือจะถูกนำออกมาเป็นตัวเลขดังนี้ จะได้ 

ลำดับที่1=1 
 
ลำดับที่2=2551
CAST( SUBSTRING_INDEX(money.idk,'/',-1) AS UNSIGNED ) AS y

คำสั่งนี้ความหมายว่า ให้เอาตัวหนังสือจากฟิลด์ money.idk ที่แยกโดยใช้เครื่องหมาย / ชุดที่ 1(นับจากหลังสุด) มาแปลงให้เป็นตัวเลข แล้วเก็บไว้ในฟิลด์ชั่วคราวที่ชื่อ y เพื่อเราจะได้เอามันไป order by ในการจัดเรียงลำดับต่อไป

เลข-1ในโค๊ดหมายถึงลำดับที่1 นับจากขวามาซ้าย ถ้าข้อมูลเราเก็บไว้ 1/2551 จะได้

ลำดับที่1=2551 
 
ลำดับที่2=1

สรุปคือถ้าเรามีข้อมูลในฟิลด์ idk ของตาราง money

ลำดับที่อยู่ใน SUBSTRING_INDEX การนับถ้าค่าเป็น+จะเป็นซ้ายไปขวา(หน้าไปหลัง) +1=ลำดับที่ 1 +2=ลำดับที่2

+1

1/2551d=1
2/2551d=2
10/2551d=10

+2

ถ้าเป็นค่าติด-ให้นับจากขวามาซ้าย(หลังมาหน้า) -1=ลำดับที่ 1 -2=ลำดับที่2

-1

1/2551d=2551
2/2551d=2551
10/2551d=2551
1/2551y=2551
2/2551y=2551
10/2551y=2551

-2

1/2551y=1
2/2551y=2
10/2551y=10

เมื่อเราเขียนคำสั่งอย่างนี้

$query_money = "SELECT *, CAST( SUBSTRING_INDEX(money.idk,'/',1) AS UNSIGNED ) AS d, CAST( SUBSTRING_INDEX(money.idk,'/',-1) AS UNSIGNED ) AS y FROM money ORDER BY y DESC , d DESC";

ตามคำสั่งนี้ถูกจัดเรียงจาก idk มากไปน้อยผลที่ได้คือ 10/2551 2/2551 1/2551 ตามลำดับที่เราต้องการแล้ว

ศึกษาฟังก์ชั่นเพิ่มได้ที่
ฟังก์ชั่น substring-index
ฟังก์ชั่น cast