การแสดงรายการที่เกี่ยวข้อง (Related)
การแสดงรายการที่เกี่ยวข้องกัน ปกติจะใช้กับพวก บทความ หรือข่าว เช่น การแบ่งบทความออกเป็นตอนๆ แล้วเชื่อมทุกตอนเข้าด้วยกันด้วย relate หรือ การแสดงข่าวของ ชมพู่ และ รายการช่าวอื่นๆของ ชมพู่ เป็นต้น
คำสั่ง SQL ด้านบนคือการค้นหารายการที่เกี่ยวข้องกัน (relate เหมือนกัน) ได้ผลลัพท์ดังตาราง
จากข้อมูลตัวอย่างด้านบน จะเห็นได้ว่า id ของรายการ ไม่ได้อยู่ใกล้เคียงกันเพียงพอที่จะทำให้ "การ Query ข้อมูลใกล้เคียงตามจำนวนที่กำหนด" สามารถแสดงผลได้อย่างถูกต้อง (ในตัวอย่างนี้หากใช้วิธีที่ผมกล่าวถึง รายการที่ 3733 จะไม่ถูกนำมาแสดงผลเลย เนื่องจากผลลัพท์จากคำสั่ง ABS() จะอยู่ห่างจากรายการที่ต้องการมากจนอาจมีรายการอื่นมาแสดงผลแทน)
การแก้ไขเราอาจต้องใช้เทคนิคอื่นในการจัดการเพิ่มเติม (ตัวอย่างนี้จะหารายการที่เกี่ยวข้องกับ id=449 จำนวน x รายการ)
ขั้นแรกเราจะ query เอารายการที่มากกว่า 449 ออกมา พร้อมใส่เลขลำดับ โดยเรียงตามลำดับ id ซึ่งจะได้ผลลัพท์ดังตาราง
หมายเหตุ ใน DB เวอร์ชั่นใหม่ๆ จะไม่สามารถเรียงลำดับใน Sub Query ได้ เพื่อให้การเรียงลำดับมีผล จึงจำเป็นต้องใส่ LIMIT เพื่อบังคับให้ DB เรียงลำดับ Query ย่อยด้วย โดยที่ตัวแปร x ให้แทนที่ด้วยจำนวนผลลัพท์ที่ต้องการ
ขั้นต่อไปเราจะ Query เอารายการก่อนรายการที่ 449
ซึ่งจะได้ผลลัพท์เป็น
นำผลลัพท์ทั้งสองส่วนมารวมกันด้วย UNION โดยเรียงลำดับตาม row และจำกัดจำนวนตามที่ต้องการ
จะได้ผลลัพท์เป็น (ผลลัพท์ตามตัวอย่างนี้ กำหนดให้ x=4)
ถ้าสังเกตุ ตอนนี้เราได้ผลลัพท์ที่ต้องการแล้ว แต่หากเอาไปแสดงผลเลย มันคงเรียงลำดับไม่ค่อยน่าดูเท่าไร ก็เลยต้องมาเรียงลำดับด้วย id อีกครั้ง (รายการใหม่ขึ้นก่อน)
และ นี่คือผลลัพท์ที่เราต้องการ
SELECT id,topic,relate FROM table_name WHERE relate='ทำเว็บให้มีคนดู'
คำสั่ง SQL ด้านบนคือการค้นหารายการที่เกี่ยวข้องกัน (relate เหมือนกัน) ได้ผลลัพท์ดังตาราง
id | topic | relate |
---|---|---|
218 | ทำเว็บให้มีคนดู (ตอนที่ 1) | ทำเว็บให้มีคนดู |
219 | ทำเว็บให้มีคนดู (ตอนที่ 2) | ทำเว็บให้มีคนดู |
398 | ทำเว็บให้มีคนดู (ตอนที่ 4) | ทำเว็บให้มีคนดู |
449 | ทำเว็บให้มีคนดู (ตอนที่ 5) | ทำเว็บให้มีคนดู |
450 | ทำเว็บให้มีคนดู (ตอนที่ 6) | ทำเว็บให้มีคนดู |
451 | ทำเว็บให้มีคนดู (ตอนที่ 7) | ทำเว็บให้มีคนดู |
452 | ทำเว็บให้มีคนดู (ตอนที่ 8) | ทำเว็บให้มีคนดู |
453 | ทำเว็บให้มีคนดู (ตอนที่ 9) | ทำเว็บให้มีคนดู |
454 | ทำเว็บให้มีคนดู (ตอนที่ 10) | ทำเว็บให้มีคนดู |
220 | ทำเว็บให้มีคนดู (ตอนที่ 3) | ทำเว็บให้มีคนดู |
3733 | ทำเว็บให้มีคนดู (ตอนที่ 11) | ทำเว็บให้มีคนดู |
การแก้ไขเราอาจต้องใช้เทคนิคอื่นในการจัดการเพิ่มเติม (ตัวอย่างนี้จะหารายการที่เกี่ยวข้องกับ id=449 จำนวน x รายการ)
SELECT @row:=@row+1 AS row,
y.* FROM (SELECT id,topic,relate FROM table_name WHERE id>449 ORDER BY id ASC LIMIT x) AS y
,(SELECT @row:=0) AS r
ขั้นแรกเราจะ query เอารายการที่มากกว่า 449 ออกมา พร้อมใส่เลขลำดับ โดยเรียงตามลำดับ id ซึ่งจะได้ผลลัพท์ดังตาราง
row | id | topic | relate |
---|---|---|---|
1 | 450 | ทำเว็บให้มีคนดู (ตอนที่ 6) | ทำเว็บให้มีคนดู |
2 | 451 | ทำเว็บให้มีคนดู (ตอนที่ 7) | ทำเว็บให้มีคนดู |
3 | 452 | ทำเว็บให้มีคนดู (ตอนที่ 8) | ทำเว็บให้มีคนดู |
4 | 453 | ทำเว็บให้มีคนดู (ตอนที่ 9) | ทำเว็บให้มีคนดู |
6 | 454 | ทำเว็บให้มีคนดู (ตอนที่ 10) | ทำเว็บให้มีคนดู |
6 | 3733 | ทำเว็บให้มีคนดู (ตอนที่ 11) | ทำเว็บให้มีคนดู |
ขั้นต่อไปเราจะ Query เอารายการก่อนรายการที่ 449
SELECT @row:=@row+1 AS row,
y.* FROM (SELECT id,topic,relate FROM table_name WHERE id<449 ORDER BY id DESC LIMIT x) AS y
,(SELECT @row:=0) AS r
ซึ่งจะได้ผลลัพท์เป็น
row | id | topic | relate |
---|---|---|---|
1 | 398 | ทำเว็บให้มีคนดู (ตอนที่ 4) | ทำเว็บให้มีคนดู |
2 | 220 | ทำเว็บให้มีคนดู (ตอนที่ 3) | ทำเว็บให้มีคนดู |
3 | 219 | ทำเว็บให้มีคนดู (ตอนที่ 2) | ทำเว็บให้มีคนดู |
4 | 218 | ทำเว็บให้มีคนดู (ตอนที่ 1) | ทำเว็บให้มีคนดู |
SELECT * FROM (
(SELECT @row:=@row+1 AS row,
y.* FROM (SELECT id,topic,relate FROM table_name WHERE id>449 ORDER BY id ASC LIMIT x) AS y
,(SELECT @row:=0) AS r)
UNION
(SELECT @row2:=@row2+1 AS row2,
y.* FROM (SELECT id,topic,relate FROM table_name WHERE id<449 ORDER BY id DESC LIMIT x) AS y
,(SELECT @row2:=0) AS r)
) AS Z ORDER BY row LIMIT x
จะได้ผลลัพท์เป็น (ผลลัพท์ตามตัวอย่างนี้ กำหนดให้ x=4)
row | id | topic | relate |
---|---|---|---|
1 | 398 | ทำเว็บให้มีคนดู (ตอนที่ 4) | ทำเว็บให้มีคนดู |
1 | 450 | ทำเว็บให้มีคนดู (ตอนที่ 6) | ทำเว็บให้มีคนดู |
2 | 220 | ทำเว็บให้มีคนดู (ตอนที่ 3) | ทำเว็บให้มีคนดู |
2 | 451 | ทำเว็บให้มีคนดู (ตอนที่ 7) | ทำเว็บให้มีคนดู |
SELECT * FROM (
SELECT * FROM (
(SELECT @row:=@row+1 AS row,
y.* FROM (SELECT id,topic,relate FROM table_name WHERE id>449 ORDER BY id ASC LIMIT 4) AS y
,(SELECT @row:=0) AS r)
UNION
(SELECT @row2:=@row2+1 AS row2,
y.* FROM (SELECT id,topic,relate FROM table_name WHERE id<449 ORDER BY id DESC LIMIT 4) AS y
,(SELECT @row2:=0) AS r)
) AS Z ORDER BY row LIMIT 4
) AS Z2 ORDER BY id DESC
และ นี่คือผลลัพท์ที่เราต้องการ
row | id | topic | relate |
---|---|---|---|
2 | 451 | ทำเว็บให้มีคนดู (ตอนที่ 7) | ทำเว็บให้มีคนดู |
1 | 450 | ทำเว็บให้มีคนดู (ตอนที่ 6) | ทำเว็บให้มีคนดู |
1 | 398 | ทำเว็บให้มีคนดู (ตอนที่ 4) | ทำเว็บให้มีคนดู |
2 | 220 | ทำเว็บให้มีคนดู (ตอนที่ 3) | ทำเว็บให้มีคนดู |