
avg() คืออะไร? ทำไมต้องคำนวณค่าเฉลี่ยใน Laravel?
ถ้าคุณเขียน Laravel อยู่แล้ว น่าจะเคยเจอ scenario หาค่าเฉลี่ยอยู่บ่อยๆ ไม่ว่าจะเป็น:
- ราคาเฉลี่ยสินค้า — ประเมินว่าร้านเราขายสินค้าราคาเฉลี่ยเท่าไหร่
- Rating เฉลี่ย — คำนวณดาวเฉลี่ยของรีวิวสินค้า
- ยอดสั่งซื้อเฉลี่ย — วิเคราะห์ยอดขายต่อออร์เดอร์
ปกติถ้าเขียน PHP แบบเดิม คงต้องใช้ foreach วนลูปบวกค่า แล้วหาร — เขียนหลายบรรทัด อ่านยาก แถมยังต้อง handle divide-by-zero ด้วยตัวเอง ยิ่งโค้ดซับซ้อนขึ้น ยิ่งเสี่ยงพลาด
Laravel มีทางออกที่ดีกว่านั้น — avg() method ที่อยู่ใน Illuminate\Support\Collection ช่วยให้คุณหาค่าเฉลี่ยได้ในบรรทัดเดียว ไม่ว่าข้อมูลจะมาจาก array, Eloquent model, หรือ API response
สิ่งสำคัญที่ต้องจำ:
avg()คืนค่าเป็นfloatหรือnull(กรณี Collection ว่าง)
แล้ว average() ล่ะ? เป็นแค่ alias — ใช้แทนกันได้เลย 100%
พื้นฐานการใช้งาน avg()
ค่าเฉลี่ยจากตัวเลขใน Collection
collect([1, 1, 2, 4])->avg();
// ผลลัพธ์: 2
// (1 + 1 + 2 + 4) / 4 = 2
ง่ายๆ แบบนี้เลย — ส่ง array ของตัวเลขเข้า collect() แล้วเรียก .avg() ต่อได้เลย
หาค่าเฉลี่ยจาก Field ที่กำหนดด้วย avg('field')
$products = collect([
['price' => 100], // หนังสือ
['price' => 200], // คอร์สเรียน
['price' => 150], // อุปกรณ์เขียนโค้ด
]);
$products->avg('price'); // ผลลัพธ์: 150
นี่คือรูปแบบที่ใช้บ่อยที่สุด — ระบุ field name ที่ต้องการหาค่าเฉลี่ย Laravel จะ loop ให้อัตโนมัติ ใช้ได้ทั้งกับ associative array และ object
average() — alias อีกชื่อ
collect([10, 20, 30])->average(); // ผลลัพธ์: 20
collect([10, 20, 30])->avg(); // ผลลัพธ์: 20
ทั้งคู่ทำงานเหมือนกันทุกประการ — เลือกใช้อันไหนก็ได้ตามความชอบ
ใช้งานขั้นสูง — ก้าวขึ้นอีกระดับ
Nested Key ด้วย Dot Notation
$orders = collect([
['product' => ['price' => 99.99]],
['product' => ['price' => 799.99]],
]);
$orders->avg('product.price'); // ผลลัพธ์: 449.99
จุดเด่นของ Laravel Collections — รองรับ dot notation สำหรับ nested array/object ไม่ต้อง loop หลายชั้น เรียก 'product.price' ตรงๆ ได้เลย ถ้าเทียบกับ PHP แบบเดิม ต้องเขียน foreach ซ้อนกัน 2 ชั้นแน่นอน
ใช้ Callback คำนวณค่าก่อนหาค่าเฉลี่ย
$orders = collect([
['price' => 100, 'qty' => 2], // order ที่ 1: 100*2 = 200
['price' => 200, 'qty' => 3], // order ที่ 2: 200*3 = 600
['price' => 150, 'qty' => 1], // order ที่ 3: 150*1 = 150
]);
// คำนวณ price * qty ก่อน แล้วค่อยหาค่าเฉลี่ย
// (200 + 600 + 150) / 3 = 316.67
$orders->avg(fn($item) => $item['price'] * $item['qty']); // ผลลัพธ์: 316.67
นี่คือสิ่งที่คู่แข่งส่วนใหญ่ยังไม่ค่อยเขียนเป็นภาษาไทย — ความสามารถในการ transform ข้อมูลก่อนหาค่าเฉลี่ย ทำให้ avg() ยืดหยุ่นมาก เหมาะกับโจทย์ที่ต้องคำนวณ derived value เช่น ยอดรวมต่อ order (price × qty)

Higher-Order Message — $collection->avg->price
$products = collect([
(object)['price' => 100],
(object)['price' => 200],
]);
$products->avg->price; // ผลลัพธ์: 150
นี่คือ syntactic sugar ที่เรียกว่า Higher-Order Message — รูปแบบย่อสำหรับ object collection โดยเฉพาะ เขียนสั้นลง แต่ต้องระวัง: ใช้ได้เฉพาะกับ object เท่านั้น ใช้กับ array ไม่ได้
Edge Cases ที่ต้องรู้ก่อนเอาไปใช้งานจริง
Empty Collection คืนค่าอะไร?
collect([])->avg(); // ผลลัพธ์: null (ไม่ใช่ 0!)
สำคัญมาก! — ถ้า Collection ว่าง จะคืน null ไม่ใช่ 0 ถ้าเอาไปใช้ต่อโดยไม่ handle อาจเกิด error ได้ แนะนำให้ใช้ ?? 0 หรือตรวจสอบด้วย is_null() ก่อน
ค่า Null กับ Non-numeric
collect([
['price' => 100],
['price' => null], // ค่า null จะถูก skip
['price' => 200],
])->avg('price'); // ผลลัพธ์: 150
- ค่า
nullใน field จะถูก skip ไม่เอามาคำนวณ - Non-numeric จะถูก cast เป็น
0หรือ ignore ขึ้นอยู่กับ PHP version
เตือน: ตรวจสอบ nullable field ใน database ให้ดีก่อนเอาค่าไปใช้ โดยเฉพาะ Eloquent model ที่ดึงจาก DB
ตัวอย่างใช้งานจริง — เขียนโค้ดให้เพื่อน Thai Dev ดู
คำนวณราคาเฉลี่ยสินค้า (E-commerce)
// จาก Eloquent model — ดึงสินค้าทั้งหมดมาหาค่าเฉลี่ย
$avgPrice = Product::all()->avg('price');
// จาก API response — parse แล้วหาค่าเฉลี่ย
$avgPrice = collect($apiProducts)->avg('price');
คำนวณ Rating เฉลี่ยของรีวิวสินค้า
$product = Product::with('reviews')->find($id);
// rating เฉลี่ยทั้งหมด
$avgRating = $product->reviews->avg('rating');
// rating เฉลี่ยเฉพาะ verified purchase
$avgVerifiedRating = $product->reviews
->filter(fn($r) => $r->is_verified) // กรองเฉพาะรีวิวที่ซื้อจริง
->avg('rating');
คำนวณยอดสั่งซื้อเฉลี่ยต่อ Order
// ยอดสั่งซื้อเฉลี่ย = ผลรวม (price * qty) ของแต่ละ order
$avgOrderValue = Order::all()->avg(fn($order) =>
$order->items->sum(fn($item) => $item->price * $item->quantity)
);
ตัวอย่างนี้เหมาะกับ admin dashboard สำหรับร้านค้าออนไลน์ไทย ที่ต้องการวิเคราะห์ยอดขายเฉลี่ยต่อออร์เดอร์
เทคนิคเพิ่มเติม: ใช้ pluck() ดึงเฉพาะ field ก่อน
$products = collect([
['name' => 'Book', 'price' => 150],
['name' => 'Pen', 'price' => 50],
['name' => 'Notebook', 'price' => 80],
]);
// ดึงเฉพาะ price มาหาค่าเฉลี่ย
$products->pluck('price')->avg(); // ผลลัพธ์: 93.33
รูปแบบ pluck()->avg() อ่านง่าย เหมาะกับกรณีที่ต้องการเฉพาะ field เดียวมาหาค่าเฉลี่ย
สรุป — จำได้ใน 1 นาที
| Syntax | การใช้งาน |
|---|---|
avg() |
ค่าเฉลี่ยจากตัวเลขใน Collection |
avg('field') |
ค่าเฉลี่ยจาก field ที่ระบุ |
avg('nested.field') |
dot notation สำหรับ nested data |
avg(fn(...)) |
คำนวณ derived value ก่อนหาค่าเฉลี่ย |
$coll->avg->field |
Higher-order message (object collection) |
| ว่าง | คืน null — อย่าลืม handle! |
average() เป็นแค่ alias ของ avg() — ใช้ตัวไหนก็ได้
จำง่ายๆ: ถ้าต้องหาค่าเฉลี่ยใน Laravel — อย่าวนลูปเอง มี
avg()ให้ใช้แล้ว
Tags: Laravel Collections, Laravel avg, Laravel average, PHP Collections, Higher-Order Message