ทำไมต้องรู้จักการคำนวณสถิติในฐานข้อมูล
เวลาเราเก็บข้อมูลใน MySQL หรือ MariaDB เราไม่ได้แค่เก็บไว้ดูเฉยๆ แต่เราต้องดึงค่าออกมาสรุปผลเพื่อใช้ในการตัดสินใจทางธุรกิจ การทำ Aggregate (การรวมกลุ่มข้อมูลเพื่อคำนวณค่าทางสถิติ) คือหัวใจสำคัญของการทำงานกับข้อมูลจำนวนมาก เหมือนกับเวลาเรามีสมุดบัญชีรายรับรายจ่ายยาวเป็นหางว่าว แล้วเราต้องการสรุปว่าเดือนนี้ใช้เงินไปเท่าไหร่กันแน่
ถ้าเราไม่มีคำสั่งพวกนี้ เราคงต้องเขียนโปรแกรมวนลูปดึงข้อมูลออกมาทีละแถวแล้วค่อยมาบวกเลขเอง ซึ่งมันช้าและกินทรัพยากรเครื่องมาก การใช้คำสั่งฐานข้อมูลโดยตรงจึงเร็วกว่าและแม่นยำกว่ามาก นี่คือทักษะที่โปรแกรมเมอร์ทุกคนต้องมีติดตัว เพราะตอนไปทำงานจริง หัวหน้ามักจะให้เราทำรายงานสรุปข้อมูลแบบนี้เสมอ
ก่อนจะเริ่มกัน ต้องมั่นใจว่าเรามีฐานข้อมูลที่พร้อมใช้งานและมีตารางข้อมูลอยู่แล้ว ถ้าใครยังไม่มี ลองนึกภาพตารางเก็บข้อมูล "ยอดขายสินค้า" ที่มีคอลัมน์ชื่อสินค้า ราคา และจำนวนที่ขายได้ เราจะใช้ฐานข้อมูลเหล่านี้แหละมาเรียนรู้การคำนวณสถิติเบื้องต้นกัน
ฟังก์ชันพื้นฐานสำหรับการคำนวณกลุ่มข้อมูล
ฟังก์ชัน Aggregate คือชุดคำสั่งที่เอาไว้คำนวณค่าจากข้อมูลหลายๆ แถวให้เหลือเพียงค่าเดียวที่เราสนใจ ตัวที่ใช้บ่อยที่สุดคือ COUNT (นับจำนวน), SUM (รวมผลบวก), AVG (หาค่าเฉลี่ย), MIN (หาค่าต่ำสุด) และ MAX (หาค่าสูงสุด)
ลองนึกภาพการตรวจข้อสอบนักเรียนทั้งห้อง แทนที่จะไล่ดูคะแนนทีละคน เราอยากรู้ว่า "คะแนนสูงสุดคือเท่าไหร่" หรือ "คะแนนเฉลี่ยทั้งห้องเป็นอย่างไร" คำสั่งเหล่านี้แหละที่จะช่วยให้เราตอบคำถามพวกนั้นได้ทันทีโดยไม่ต้องนั่งไล่ดูรายชื่อเอง
การใช้งานฟังก์ชันพวกนี้จะทำผ่านคำสั่ง SELECT (คำสั่งดึงข้อมูล) โดยระบุชื่อฟังก์ชันและคอลัมน์ที่ต้องการไว้ข้างในวงเล็บ ถ้าเราต้องการคำนวณทั้งตาราง เราก็แค่เขียนคำสั่งลงไปตรงๆ ได้เลย
-- นับจำนวนสินค้าทั้งหมดในตาราง
SELECT COUNT(*) FROM products;
-- หาผลรวมราคาขายทั้งหมด และราคาเฉลี่ย
SELECT SUM(price), AVG(price) FROM products;
-- หาว่าสินค้าราคาถูกที่สุดและแพงที่สุดคือเท่าไหร่
SELECT MIN(price), MAX(price) FROM products;
ส่วนแรกคือ COUNT(*) ใช้เพื่อบอกว่าตารางนี้มีข้อมูลทั้งหมดกี่แถว ส่วนที่สอง SUM และ AVG ใช้สำหรับข้อมูลตัวเลขเพื่อดูยอดรวมและค่าเฉลี่ย ส่วนสุดท้าย MIN และ MAX ช่วยให้เราเห็นช่วงของราคาที่ขายจริงในร้านค้าของเรา ผลลัพธ์ที่ได้จะเป็นตัวเลขสรุปออกมาเป็นหนึ่งบรรทัดตามจำนวนฟังก์ชันที่เราเรียกใช้
การจัดกลุ่มข้อมูลด้วยคำสั่ง GROUP BY
บ่อยครั้งที่เราไม่ได้อยากรู้ค่าสรุปของทั้งตาราง แต่เราอยากรู้ค่าสรุป "รายกลุ่ม" มากกว่า เช่น อยากรู้ว่าสินค้าแต่ละประเภทมียอดขายรวมเท่าไหร่ GROUP BY (คำสั่งจัดกลุ่มข้อมูลที่มีค่าซ้ำกันไว้ด้วยกัน) จึงเข้ามามีบทบาทในจุดนี้
ลองเปรียบเทียบกับการจัดหมวดหมู่เสื้อผ้าในตู้ แทนที่จะกองรวมกันหมด เราแยกเป็นกลุ่มเสื้อยืด กลุ่มกางเกง และกลุ่มถุงเท้า เพื่อให้ง่ายต่อการหยิบใช้ การ GROUP BY ก็คือการบอกฐานข้อมูลว่า ให้รวมแถวที่มีค่าในคอลัมน์นั้นเหมือนกันเข้าเป็นกลุ่มเดียวกันก่อน แล้วค่อยคำนวณสถิติแยกรายกลุ่มให้เรา
จุดที่มือใหม่พลาดบ่อยคือการลืมใส่คอลัมน์ที่ต้องการแสดงผลไว้ใน GROUP BY ด้วย ซึ่งถ้าทำแบบนั้นฐานข้อมูลจะแจ้งเตือนความผิดพลาดทันที จำไว้ว่าถ้าอยากเห็นชื่อกลุ่ม ต้องใส่ชื่อคอลัมน์นั้นไว้ในส่วนของ SELECT และ GROUP BY เสมอ
-- นับจำนวนสินค้าแยกตามประเภท
SELECT category, COUNT(*)
FROM products
GROUP BY category;
ในบรรทัดแรกเราเลือกคอลัมน์ category เพื่อดูชื่อกลุ่ม และใช้ COUNT(*) เพื่อดูจำนวนสินค้าในกลุ่มนั้น บรรทัดที่สองระบุตารางที่ใช้ และบรรทัดสุดท้ายคือการสั่งให้ฐานข้อมูลจัดกลุ่มตามประเภทสินค้า ผลลัพธ์จะออกมาเป็นตารางที่มีสองคอลัมน์ คือชื่อประเภทและตัวเลขจำนวนสินค้าที่นับได้ในแต่ละประเภทนั้น
การกรองข้อมูลกลุ่มด้วย HAVING
เมื่อเราจัดกลุ่มแล้ว บางครั้งเราก็ไม่ได้อยากเห็นข้อมูลทุกกลุ่ม เราต้องการเห็นแค่บางกลุ่มที่เข้าเงื่อนไขเท่านั้น เช่น "แสดงเฉพาะกลุ่มสินค้าที่มีจำนวนเกิน 10 ชิ้น" ที่นี่เราจะใช้ HAVING (คำสั่งกรองข้อมูลหลังจากการจัดกลุ่ม) มาเป็นตัวช่วย
หลายคนมักสับสนระหว่าง WHERE (คำสั่งกรองข้อมูลก่อนจัดกลุ่ม) กับ HAVING ให้จำง่ายๆ ว่า WHERE เอาไว้กรองข้อมูลดิบก่อนจะเริ่มนับหรือรวม แต่ HAVING เอาไว้กรองผลลัพธ์สุดท้ายหลังจากที่เราคำนวณสถิติเสร็จเรียบร้อยแล้วเท่านั้น
สถานการณ์ที่ต้องใช้ HAVING คือตอนที่เราต้องการหาข้อมูลที่ "พิเศษ" กว่าปกติ เช่น อยากหาหมวดหมู่สินค้าที่ทำเงินได้มากกว่า 10,000 บาทต่อเดือน เพื่อที่เราจะได้โฟกัสการตลาดไปที่กลุ่มนั้นเป็นพิเศษ
-- แสดงเฉพาะกลุ่มที่มีสินค้ามากกว่า 5 รายการ
SELECT category, COUNT(*)
FROM products
GROUP BY category
HAVING COUNT(*) > 5;
คำสั่งนี้จะทำการนับสินค้าแยกตามประเภทก่อน จากนั้นจึงค่อยเช็คว่ากลุ่มไหนมีจำนวนสินค้าเกิน 5 ชิ้น ถ้ากลุ่มไหนมีน้อยกว่านั้นก็จะถูกกรองออกไปจากผลลัพธ์ ผลลัพธ์ที่ได้จะเป็นตารางที่แสดงเฉพาะกลุ่มที่มีสินค้าค่อนข้างเยอะ ช่วยให้เราเห็นภาพรวมของกลุ่มสินค้าที่เป็นสินค้าหลักของร้านได้ทันที
ข้อควรระวังสำหรับโปรแกรมเมอร์มือใหม่
ปัญหาที่พบบ่อยที่สุดคือการใส่คอลัมน์ใน SELECT ที่ไม่ได้อยู่ในการ GROUP BY ซึ่งจะทำให้ผลลัพธ์ที่ได้ไม่ถูกต้อง หรือในบางโหมดของ MySQL จะสั่งให้คำสั่งทำงานไม่ได้เลย ต้องระวังให้ดีว่าคอลัมน์ที่เราเลือกมาแสดง ต้องเป็นคอลัมน์ที่อยู่ในกลุ่มที่เราจัดไว้แล้วเท่านั้น
อีกเรื่องคือประสิทธิภาพของฐานข้อมูล การใช้ COUNT(*) บนตารางที่มีข้อมูลเป็นล้านแถวอาจจะใช้เวลานาน ถ้าเราทำบ่อยๆ อาจต้องมีการทำ Indexing (การสร้างดัชนีช่วยให้ค้นหาข้อมูลเร็วขึ้น) เข้ามาช่วย เพื่อให้การ Query ข้อมูลไม่ทำให้เว็บไซต์ของเราโหลดช้าจนเกินไป
การตั้งชื่อคอลัมน์ที่นำมาคำนวณก็สำคัญ ควรใช้ AS (คำสั่งตั้งชื่อเล่นให้คอลัมน์) เพื่อให้ผลลัพธ์ที่ออกมาดูอ่านง่าย เช่น แทนที่จะแสดงชื่อฟังก์ชันยาวๆ ให้เปลี่ยนเป็นชื่อที่เข้าใจง่าย เช่น total_items หรือ average_price จะช่วยให้เราเอาข้อมูลไปใช้ต่อในโค้ดฝั่งโปรแกรมได้ง่ายขึ้น
สรุป: การนำไปใช้ในโปรเจกต์จริง
การเข้าใจเรื่อง GROUP BY และ HAVING จะเปลี่ยนวิธีการทำงานของคุณไปเลย จากเดิมที่ต้องดึงข้อมูลทั้งหมดมาประมวลผลในโค้ดภาษาโปรแกรม คุณจะสามารถสั่งให้ฐานข้อมูลทำงานให้เสร็จตั้งแต่ต้นทาง ซึ่งเร็วกว่าและมีประสิทธิภาพมากกว่ามาก
ลองนึกภาพคุณกำลังทำระบบ Dashboard (หน้าจอแสดงผลสถิติ) ให้กับร้านค้าออนไลน์ สิ่งที่คุณต้องทำคือการเขียน Query เหล่านี้เพื่อดึงยอดขายรายวัน รายเดือน หรือรายสินค้า เพื่อส่งข้อมูลไปแสดงเป็นกราฟบนหน้าเว็บ นี่คือทักษะที่คุณจะได้ใช้ตั้งแต่โปรเจกต์แรกที่เรียนจบ
ฝึกฝนด้วยการลองทำโปรเจกต์จริง อย่าเพียงแค่อ่านผ่านๆ ให้ลองสร้างตารางข้อมูลจำลองขึ้นมา แล้วลองเขียนคำสั่งเหล่านี้เพื่อหาคำตอบจากข้อมูลนั้นจริงๆ เมื่อคุณเริ่มคล่อง คุณจะพบว่าฐานข้อมูลเป็นเครื่องมือที่ทรงพลังมากในการจัดการข้อมูล และนั่นคือก้าวสำคัญในการเป็นโปรแกรมเมอร์ที่เก่งและทำงานได้จริงครับ