แสดงบทความที่มีป้ายกำกับ algorithm แสดงบทความทั้งหมด
แสดงบทความที่มีป้ายกำกับ algorithm แสดงบทความทั้งหมด

วันเสาร์ที่ 26 ตุลาคม พ.ศ. 2556

การเรียงลำดับภาษาไทยใน php / sorting thai characters


ในการเรียงลำดับโดย php ถ้าใช้ฟังค์ชั่น sort ธรรมดา จะเรียงทีละ byte หรือเรียงโดยให้ความสำคัญกับสระเท่าพยัญชนะจะทำให้เกิดการเรียงลำดับภาษาไทยที่ผิดพลาดดังนนี้ครับ

การบ้าน,ข้าว,เคย,โค,ไก่,ไข่

(ทำให้คำที่ขึ้นต้นด้วยสระเดียวกันเช่น ไ (สระไอไม้มาลัย) อยู่ติดกัน)
ใน php เราจะใช้การตั้งค่า locale และใช้ usort (User sort) ช่วยให้จัดเรียงลำดับภาษาไทยได้ถูกต้อง ดังนี้ครับ..

function sortthaitis620(&$a){
    setlocale(LC_COLLATE, 'thai');
    usort ($a, 'strcoll');
}
function sortthai(&$a){//สำหรับ utf8
    foreach($a as &$i){
      $i = iconv('UTF-8','TIS-620',$i);
    }
    setlocale(LC_COLLATE, 'thai');
    usort ($a, 'strcoll');
    foreach($a as &$i){
      $i = iconv('TIS-620','UTF-8',$i);
    }
}
$a = array('โค','เคย','ไก่','การบ้าน','ข้าว','ไข่');
sortthai($a);
echo implode(',',$a);

sortthaitis620 เป็น function สำหรับ เรียงลำดับข้อความภาษาไทยในตัวอักษรที่เข้ารหัสแบบ tis620 หรือ windows874

sortthai เป็น function สำหรับ เรียงลำดับข้อความภาษาไทยในตัวอักษรที่เข้ารหัสแบบ utf8 ครับ

แต่ถ้าต้องการเรียงลำดับข้อมูลในตารางของฐานข้อมูล mysql ที่ encoding เป็น utf8 ให้ select ดังนี้ครับ
SELECT * FROM tb ORDER BY CONVERT (column_name USING tis620);

วันศุกร์ที่ 14 มิถุนายน พ.ศ. 2556

การค้นหาแบบช่วงวันที่

สมมติว่า $date_start_search และ $date_end_search เป็นข้อมูลจากช่องกรอกข้อมูลวันที่
ในรูปแบบ yyyy-mm-dd ตัวอย่างเช่น 2013-01-01

กรณี 1
ช่วงวันที่ค้นหา(ทั้งหมด) อยู่ข้างในระหว่างช่วงวันที่ในฐานข้อมูล
.............|---------------|.................ช่วงวันที่ค้นหา
........||==============||.............ช่วงวันที่ในฐานข้อมูล
.............(---------------).................ช่วงข้อมูลที่ได้รับจากฐานข้อมูล
อยู่ในรูปของ sql query:
SELECT * FROM date_test WHERE
'$date_start_search' >= date_start AND '$date_end_search' <= date_end

กรณี 2
ช่วงช่วงวันที่ในฐานข้อมูล(บางส่วน) อยู่ข้างในช่วงวันที่ค้นหา
....|---------------|
.........||============||
.........(-----------)
หรือ
..........................|---------------|
.........||============||
........................(--------)
อยู่ในรูปของ sql query:
SELECT * FROM date_test WHERE date_start BETWEEN '$date_start_search' AND '$date_end_search'
SELECT * FROM date_test WHERE date_end BETWEEN '$date_start_search' AND '$date_end_search'
ตามลำดับ

กรณี 3
ช่วงวันที่ในฐานข้อมูล(ทั้งหมด) อยู่ข้างในระหว่างช่วงวันที่ที่ค้นหา
.....|------------------------------|
.........||============||
.........(-------------------)
อยู่ในรูปของ sql query:
SELECT * FROM date_test WHERE
date_start >= '$date_start_search' AND date_end <= '$date_end_search'


- เพียงแค่ query ของกรณีที่ 2 ก็ครอบคลุมกรณีที่ 3 แล้ว
- ส่วนกรณีที่ 2 ยังไม่ครอบคลุมกรณีที่ 1 เนื่องจากในกรณีที่ 1
ทั้ง date_start และ date_end ไม่ได้อยู่ข้างใน $date_start_search, $date_end_search
ทำให้ query ของกรณีที่ 2 ไม่สามารถค้นพบหากเกิดกรณีที่ 1 ขึ้น

ดังนั้น query ที่สมบูรณ์จะอยู่ในรูปแบบ

SELECT * FROM date_test WHERE
( '$date_start_search' >= date_start AND '$date_end_search' <= date_end )
OR ( date_start BETWEEN '$date_start_search' AND '$date_end_search' )
OR ( date_end BETWEEN '$date_start_search' AND '$date_end_search' )

ก็จะเป็นคำสั่งค้นหาข้อมูลในฐานข้อมูลที่อยู่ในช่วงวันที่ๆ ต้องการครับ :)