0Pricing
SQL Interview Prep · บทเรียน

ฟังก์ชันรวมโดยไม่มี GROUP BY

วิธีที่ฟังก์ชันรวมเปล่า ๆ ยุบทั้งตารางให้เหลือหนึ่งแถว

ฟังก์ชันรวมโดยไม่มี GROUP BY เป็นบทเรียน SQL Interview Prep ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน SQL Interview Prep และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส SQL Interview Prep มีบทเรียนทั้งหมด 4 บทเรียน

หนึ่งฟังก์ชันรวมค่า หนึ่งแถว

ผู้สัมภาษณ์มักทดสอบแนวคิดพื้นฐานด้วยคำถามนี้: “จะเกิดอะไรขึ้นเมื่อใช้ฟังก์ชันรวมค่าโดยไม่มี GROUP BY”

คำตอบคือ ตารางทั้งหมดจะถูกรวมเป็นแถวเดียว ฟังก์ชันรวมค่าจะมองแถวที่ผ่านเงื่อนไขทั้งหมดเป็นกลุ่มโดยนัยขนาดใหญ่หนึ่งกลุ่ม การเข้าใจแนวคิดเรื่อง “กลุ่มโดยนัย” จะช่วยอธิบายกฎอื่น ๆ ที่ตามมาได้ ดังนั้นเรามาค่อย ๆ ทำความเข้าใจกัน

กลุ่มเดียวโดยนัย

เมื่อเขียนฟังก์ชันรวมค่าโดยไม่มี GROUP BY SQL จะทำงานเสมือนว่ามีกลุ่มหนึ่งกลุ่มที่มีทุกแถวอยู่ภายใน ผลลัพธ์จะมีหนึ่งแถวพอดีเสมอ ไม่ว่าตารางจะมีแถวมากน้อยเพียงใด — แม้ตารางจะว่างเปล่าก็ตาม

ดังนั้น SELECT COUNT(*) FROM employees จะคืนหนึ่งแถวที่มีตัวเลขหนึ่งค่า ซึ่งสรุปข้อมูลของทั้งตาราง

SELECT COUNT(*) AS total_employees
FROM employees;
-- always returns exactly one row

การใช้ฟังก์ชันรวมค่าหลายตัวร่วมกัน

คุณสามารถระบุฟังก์ชันรวมค่าหลายตัวในคำสั่ง SELECT เดียวได้ ฟังก์ชันทั้งหมดจะสรุปกลุ่มโดยนัยเดียวกัน ดังนั้นผลลัพธ์จึงยังคงมีหนึ่งแถวพอดี แต่มีหลายคอลัมน์

นี่คือคำสั่งมาตรฐานสำหรับ “ขอสถิติสรุปให้ฉัน” ตัวเลขทั้งสี่ค่าจะอธิบายชุดแถวทั้งหมดชุดเดียวกัน

SELECT
  COUNT(*)     AS num_rows,
  SUM(salary)  AS total_pay,
  AVG(salary)  AS avg_pay,
  MAX(salary)  AS top_pay
FROM employees;

ข้อผิดพลาดจากการผสม

นี่คือกฎที่มักถูกถามมากที่สุด คุณไม่สามารถผสมฟังก์ชันรวมค่าเดี่ยวกับคอลัมน์ที่ไม่ได้ผ่านการรวมค่าใน SELECT เดียวกันโดยไม่มี GROUP BY ได้

เหตุผลคือ ฟังก์ชันรวมค่าจะสร้างหนึ่งแถว แต่คอลัมน์ธรรมดามีหลายค่า แล้วควรจะแสดงค่าใด ความหมายจึงกำกวม ดังนั้น SQL มาตรฐานจึงแจ้งข้อผิดพลาด

-- ERROR: name is not aggregated and there is no GROUP BY
SELECT name, MAX(salary)
FROM employees;

เหตุใดจึงกำกวม

ลองพิจารณาจากตารางของเรา MAX(salary) รวมทุกแถวให้เหลือค่าเดียว แต่ name มีค่าต่างกันในทุกแถว แถวสรุปเพียงแถวเดียวไม่สามารถเก็บชื่อห้าชื่อไว้ในเซลล์เดียวได้

ฐานข้อมูลจะไม่เดาสุ่ม นี่คือหลักการเดียวกับกฎของ GROUP BY: คอลัมน์ที่เลือกทุกคอลัมน์ต้องผ่านการรวมค่าหรือเป็นส่วนหนึ่งของกลุ่ม เมื่อไม่มี GROUP BY จึงอนุญาตให้ใช้ได้เฉพาะฟังก์ชันรวมค่า

ข้อยกเว้นแบบผ่อนปรนของ MySQL

มีรายละเอียดเฉพาะของภาษาย่อยหนึ่งอย่างที่ควรรู้: MySQL รุ่นเก่าหรือที่ไม่ใช่โหมดเข้มงวดจะยอมให้ใช้คำสั่งที่ผสมกัน และคืนชื่อแบบโดยพลการ ซึ่งไม่จำเป็นต้องเป็นชื่อผู้มีรายได้สูงสุด

MySQL รุ่นปัจจุบันที่เปิดใช้ ONLY_FULL_GROUP_BY (ซึ่งเป็นค่าเริ่มต้นในปัจจุบัน) จะปฏิเสธคำสั่งนี้เช่นเดียวกับระบบอื่น การกล่าวถึงเรื่องนี้แสดงว่าคุณเข้าใจความแตกต่างระหว่างภาษาย่อย แต่ให้ถือว่าคำสั่งที่ผสมกันนี้ไม่ถูกต้องเสมอ

การดึงแถวที่มีค่า MAX

แล้วจะดึงชื่อพนักงานที่ได้รับเงินเดือนสูงสุดได้อย่างไร ไม่ใช่ด้วยการผสมคอลัมน์ ให้ใช้ ORDER BY + LIMIT หรือใช้คำสั่งย่อยที่เปรียบเทียบกับค่าที่ได้จากฟังก์ชันรวม

วิธีใช้ ORDER BY/LIMIT เป็นวิธีที่ง่ายที่สุด ส่วนวิธีใช้คำสั่งย่อยสามารถปรับใช้ได้กว้างกว่า และคืนพนักงานทุกคนที่มีค่าสูงสุดเท่ากัน

-- Subquery: returns everyone earning the max
SELECT name, salary
FROM employees
WHERE salary = (SELECT MAX(salary) FROM employees);

ฟังก์ชันรวมค่ากับตารางว่าง

นี่คือกรณีขอบที่ผู้สัมภาษณ์มักแทรกเข้ามาถาม: “ฟังก์ชันรวมค่าเดี่ยวจะคืนอะไรเมื่อใช้กับตารางว่าง”

  • COUNT(*) คืนค่า 0 (หนึ่งแถวที่มีค่าเป็น 0)
  • SUM, AVG, MIN, MAX คืนค่า NULL (หนึ่งแถวที่มีค่าเป็น NULL)

ที่สำคัญคือคุณยังคงได้หนึ่งแถวกลับมา ไม่ใช่ไม่มีแถวเลย หลักประกันเรื่องหนึ่งแถวนี้คือจุดประสงค์ทั้งหมดของการใช้ฟังก์ชันรวมค่าโดยไม่มี GROUP BY

SELECT COUNT(*) AS c, SUM(salary) AS s, MAX(salary) AS m
FROM employees
WHERE 1 = 0;
-- one row: c=0, s=NULL, m=NULL

ห้ามใช้ฟังก์ชันรวมค่าใน WHERE

อีกกฎหนึ่งที่ตามมาจากแนวคิดนี้คือ คุณไม่สามารถใส่ฟังก์ชันรวมค่าไว้ในส่วนคำสั่ง WHERE ได้ เพราะ WHERE จะกรองแถวแต่ละแถวก่อนที่จะเกิดการรวมค่า

หากต้องการกรองจากผลลัพธ์ของฟังก์ชันรวมค่า ให้ใช้ HAVING (ร่วมกับการจัดกลุ่ม) หรือห่อฟังก์ชันรวมค่าไว้ในคำสั่งย่อย WHERE ทำงานเร็วเกินไปตามลำดับการทำงาน จึงมองไม่เห็นผลลัพธ์ของฟังก์ชันรวมค่า

-- ERROR: aggregate not allowed in WHERE
-- SELECT * FROM employees WHERE salary > AVG(salary);

-- Correct: compare to the aggregate via subquery
SELECT name, salary
FROM employees
WHERE salary > (SELECT AVG(salary) FROM employees);

ฟังก์ชันรวมค่าเดี่ยวเทียบกับ GROUP BY

ลองเปรียบเทียบให้เห็นความแตกต่าง:

  • ไม่มี GROUP BY: กลุ่มโดยนัยหนึ่งกลุ่ม = ตารางทั้งหมด = ผลลัพธ์หนึ่งแถวพอดี
  • มี GROUP BY คอลัมน์: หนึ่งกลุ่มต่อค่าที่แตกต่างกันของคอลัมน์ = หนึ่งแถวต่อกลุ่ม

ฟังก์ชันรวมค่าเดี่ยวก็คือ GROUP BY ที่มีคอลัมน์สำหรับจัดกลุ่มเป็นศูนย์ ใช้กลไกเดียวกัน เพียงรวมทุกอย่างไว้ในกลุ่มใหญ่หนึ่งกลุ่ม

-- Whole table: one row
SELECT AVG(salary) FROM employees;

-- Per department: one row each
SELECT department, AVG(salary)
FROM employees
GROUP BY department;

วิธีอธิบาย

คำตอบที่ชัดเจนคือ “ฟังก์ชันรวมค่าโดยไม่มี GROUP BY จะมองชุดผลลัพธ์ทั้งหมดเป็นกลุ่มโดยนัยหนึ่งกลุ่ม และคืนแถวสรุปหนึ่งแถวพอดี แม้ตารางจะว่างเปล่า คุณไม่สามารถเลือกคอลัมน์ที่ไม่ได้ผ่านการรวมค่าร่วมกับฟังก์ชันนี้ได้ เพราะค่านั้นจะกำกวม หากต้องการแถวที่อยู่เบื้องหลัง MAX หรือ MIN ผมจะใช้ ORDER BY ร่วมกับ LIMIT หรือใช้คำสั่งย่อยที่เปรียบเทียบกับฟังก์ชันรวมค่า”

ตรวจสอบอย่างรวดเร็ว

ลองทำนายรูปแบบผลลัพธ์

สรุป

ฟังก์ชันรวมค่าโดยไม่มี GROUP BY โดยสรุป:

  • ตารางทั้งหมดกลายเป็นกลุ่มโดยนัยหนึ่งกลุ่ม → ผลลัพธ์หนึ่งแถวพอดี
  • ไม่สามารถผสมฟังก์ชันรวมค่าเดี่ยวกับคอลัมน์ที่ไม่ได้ผ่านการรวมค่าได้
  • ตารางว่าง: COUNT(*) = 0 ส่วนฟังก์ชันอื่นคืนค่าเป็น NULL และยังคงมีหนึ่งแถว
  • ฟังก์ชันรวมค่าไม่สามารถปรากฏใน WHERE ได้ ให้ใช้คำสั่งย่อยหรือ HAVING
  • หากต้องการแถวที่มีค่า MIN/MAX ให้ใช้ ORDER BY + LIMIT หรือคำสั่งย่อย

แบบฝึกหัดการสัมภาษณ์เรื่องฟังก์ชันรวมค่าจบลงเพียงเท่านี้

คำถามที่พบบ่อย

บทเรียน “ฟังก์ชันรวมโดยไม่มี GROUP BY” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “ฟังก์ชันรวมโดยไม่มี GROUP BY” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส SQL Interview Prep ให้อัปเกรดเป็น CoddyKit PRO คอร์ส SQL Interview Prep มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “ฟังก์ชันรวมโดยไม่มี GROUP BY”

วิธีที่ฟังก์ชันรวมเปล่า ๆ ยุบทั้งตารางให้เหลือหนึ่งแถว คุณปฏิบัติ SQL Interview Prep ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน SQL Interview Prep หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน SQL Interview Prep บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน

บทเรียน “ฟังก์ชันรวมโดยไม่มี GROUP BY” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน SQL Interview Prep นี้ได้ไหม

ได้ บทเรียน SQL Interview Prep ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. COUNT(*) เทียบกับ COUNT(column) เทียบกับ COUNT(DISTINCT)
  2. SUM และ AVG กับ NULL
  3. MIN, MAX และการรวมค่าที่ไม่ใช่ตัวเลข
  4. ฟังก์ชันรวมโดยไม่มี GROUP BY
← กลับไปที่ SQL Interview Prep