รู้จักภาษา ABAP เปิดเบื้องหลังของ SAP R/3 ตอน 5 เรียงลำดับของข้อมูลที่อ่านได้


1,467 ผู้ชม


เรียงลำดับของข้อมูลที่อ่านได้

โดยปกติแล้วข้อมูลที่อ่านได้ที่ Result Set จะเรียงลำดับตาม Primary Key แต่ถ้าเราต้องการอ่านข้อมูล โดยให้มีการเรียงลำดับของข้อมูลตามฟิลด์อื่นๆ ที่ไม่ใช่ Primary Key ให้ใช้ออปชัน Order by ในคำสั่ง Select เช่น สมมุติว่าเราต้องการอ่านข้อมูลของตาราง customers ทั้งหมด โดยให้เรียงลำดับตามชื่อของลูกค้า เราสามารถเขียนโปรแกรมได้ดังนี้

Tables customers.
Select * from customers order by name.
Write: / customers-name, customers-city.
Endselect.

ซึ่งโดยปกติของการเรียงลำดับของข้อมูลจะเรียงจากน้อยไปหามาก ถ้าเราต้องการเรียงลำดับจากมากไปหาน้อยก็ให้เราใช้ออปชัน descending เช่น

Tables customers.
Select * from customers order by name descending.
Write: / customers-name,customers-city.
Endselect.

แต่ในทางปฏิบัติแล้ว การเรียงลำดับของข้อมูลจากออปชัน Order by นั้นไม่ค่อยจะดีสักเท่าไร ถ้าคำนึงถึงเรื่องของประสิทธิภาพ เพราะเป็นการเรียงลำดับของข้อมูลที่ Database Server ทางที่ดีกว่าก็คือการเรียงลำดับที่ Memory Space โดยใช้ Internal Table ซึ่งผมจะได้กล่าวถึงในตอนต่อไป

Table Join

ในการอ่านข้อมูลจากฐานข้อมูลที่ Database Server นั้น ถ้าเป็นการอ่านข้อมูลจากตารางเพียงตารางเดียว โลกของคนเขียนโปรแกรม ABAP ก็คงเป็นสีชมพูเป็นแน่แท้ แต่ในโลกแห่งความเป็นจริง เรามักจะพบว่าข้อมูลที่ปรากฏอยู่ในรายงาน มักจะมาจากหลายตาราง ไม่ใช่เพียงตารางเดียวอย่างที่ทุกคนฝันกัน ลองมาดูตัวอย่างของระบบงานสักตัวอย่าง สมมติว่าในระบบขายมีตารางที่สัมพันธ์กันในฐานข้อมูลดังนี้
รู้จักภาษา ABAP เปิดเบื้องหลังของ SAP R/3 ตอน 5 เรียงลำดับของข้อมูลที่อ่านได้
ตาราง zcustomer
รู้จักภาษา ABAP เปิดเบื้องหลังของ SAP R/3 ตอน 5 เรียงลำดับของข้อมูลที่อ่านได้
ตาราง zsale
รู้จักภาษา ABAP เปิดเบื้องหลังของ SAP R/3 ตอน 5 เรียงลำดับของข้อมูลที่อ่านได้
ตาราง zproduct

โดยที่ตาราง zcustomer สัมพันธ์กับตาราง zsale ด้วยฟิลด์ id กับ cust_id ตามลำดับ และตาราง zsale กับตาราง zproduct สัมพันธ์กันด้วยฟิลด์ p_id ในการอ่านข้อมูลจากตารางในฐานข้อมูลที่มากกว่า 1 ตารางนั้น ในระบบ SAP สามารถทำได้ 4 วิธีด้วยกันคือ
    1. Nested Select 2. Internal Table 3. View 4. Inner Join Select

สำหรับ Nested Select (หรือการ Select ซ้อน) ซึ่งเป็นวิธีการดั้งเดิมสมัย SAP Release 3.0 ผมคงไม่กล่าวถึงนะครับ เพราะเป็นวิธีที่ทำงานช้าที่สุดในการอ่านข้อมูลที่ฐานข้อมูล ดังนั้นถ้าทำใจลืมได้ก็กรุณาลืมไปเสียเถอะครับ ส่วน Internal Table นั้นเอาไว้ค่อยไปเรียนรู้กันในตอนที่ผมพูดถึง Internal Table ก็แล้วกัน ส่วน View นั้นก็เป็นการสร้าง View ที่ Data Dictionary แต่วิธีที่ผมจะกล่าวถึงในส่วนนี้ก็คือ Inner Join Select นั่นเอง ผมแนะนำให้ใช้วิธีนี้ในการอ่านข้อมูลของตารางที่มากกว่า 2 ตารางขึ้นไป เพราะเป็นวิธีที่มีประสิทธิภาพค่อนข้างดีมาก และมีความคล่องตัวในการเขียนโปรแกรมมากกว่าวิธีอื่น สำหรับรูปแบบซินแท็กซ์ของ Inner Join ในคำสั่ง Select จะเป็นดังนี้

Select <table>~<field> ...
Into <table>-<field> ...
From <table1> inner join <table 2>
On <table 1>~<field> = <table 2>~<field> and ...
Where <table>~<field> ... <condition> ...

เช่น ถ้าเราต้องการแสดงข้อมูลดังต่อไปนี้จากตารางในระบบขาย
zcustomer-name zsale-p_id zsale-qty
หรือต้องการแสดงข้อมูลว่ามีลูกค้าชื่ออะไร ได้ซื้อสินค้าอะไร เป็นปริมาณเท่าไร เราสามารถเขียนโปรแกรมได้ดังนี้

Tables: zcustomer, zsale.
Select zcustomer~name zsale~p_id zsale~qty
Into (zcustomer-name, zsale-p_id, zsale-qty)
From zcustomer inner join zsale
On zcustomer~id = zsale~cust_id.
Write: / zcustomer-name, zsale-p_id, zsale-qty.
Endselect.

โปรดสังเกตว่า ในการระบุชื่อตารางกับฟิลด์ใน Inner Join ของคำสั่ง Select นั้น เราจะใช้เครื่องหมาย "~" เสมอ ยกเว้นที่ส่วน into เท่านั้นที่เราจะต้องระบุเป็น Structure เพราะสิ่งที่อยู่หลัง into ในคำสั่ง Select นั้น จะเป็นสิ่งที่อยู่ใน Memory Space นั่นเอง และในการใช้ Inner Join นั้น สิ่งแรกที่เราจะต้องทราบก่อนก็คือ ตารางที่เกี่ยวข้องทั้งหมดนั้นสัมพันธ์กันด้วยฟิลด์อะไรบ้าง
โดยหลักการง่ายๆ ของการใช้ Inner Join ที่ผมใช้ในการเขียนโปรแกรมจะมีดังนี้
  • ให้พิจารณาสิ่งที่เราต้องการในรายงาน ว่าต้องการข้อมูลในฟิลด์ของตารางใด จากตัวอย่างคือ zcustomer-name, zsale-p_id และ zsale-qty จะเห็นได้ว่ามีตารางที่เกี่ยวข้องอยู่ 2 ตารางด้วยกันคือ zcustomer และ zsale จากนั้นให้สร้าง Table Structure จากคำสั่ง Tables: zcustomer, zsale เพื่อรอรับการทำงานของคำสั่ง Select โดยที่จริงๆ แล้วในส่วนนี้ เราอาจสร้างตัวแปรมารอรับข้อมูลที่ได้จาก select ก็ได้
  • จากนั้นจากโจทย์ที่ต้องการ เราก็เลือกข้อมูลจากคำสั่ง Select ดังนี้ Select zcustomer~name zsale~p_id zsale~qty
  • เมื่ออ่านข้อมูลขึ้นมาได้แล้วจะเก็บไว้ที่ไหน? จากออปชัน into ก็คือที่ Table Structure ที่เราสร้างรอไว้นั่นเอง Into (zcustomer-name, zsale-p_id, zsale-qty)
  • ต่อมาเป็นการอ่านข้อมูลจากตารางที่สัมพันธ์กันคือ
    From zcustomer inner join zsale
    ที่ส่วนของ From ... inner join ... นี้ เราสามารถสลับตารางทางซ้ายกับตารางทางขวาของ inner join อย่างไรก็ได้ เพราะ inner join คือการอ่านข้อมูลที่สัมพันธ์กันเท่านั้น
  • จากนั้นเราจะระบุว่าทั้ง 2 ตารางสัมพันธ์กันด้วยฟิลด์อะไรจากออปชัน on ดังนี้
    On zcustomer~id = zsale~cust_id.
  • สุดท้ายก็แสดงข้อมูลที่ต้องการออกมาจากคำสั่ง Write ซึ่งเป็นข้อมูลที่ได้จากออปชัน into ของคำสั่ง Select นั่นเอง และจะต้องปิดด้วย Endselect อย่างเดียวเท่านั้น
    เชื่อผมเถอะครับ ใช้หลักการง่ายๆ อันนี้ จะช่วยให้เขียนโปรแกรมสำหรับอ่านข้อมูลจากตารางที่มากกว่า 1 ตารางได้อย่างง่ายดายในพริบตา ท่องให้ขึ้นใจนะครับสำหรับ inner join ว่า "อยากได้อะไรก็ให้ Select มันมา จากนั้นอ่านขึ้นมาได้จะ into ในไหน และอ่านจาก From ตารางอะไร inner join กับตารางอะไร ด้วยเงื่อนไข on ที่ตารางทั้งสองสัมพันธ์กันด้วยฟิลด์อะไรบ้าง" เพียงแค่นี้ก็จะทำให้คุณลืม Nested Select ไปได้ในทันที

  • PC Magazine

    ฉบับที่ 47 ธันวาคม 2545
    อ่านบทความอื่นๆ >>

    อัพเดทล่าสุด