Mệnh đề GROUP BY trong MySQL

Mệnh đề GROUP BY trong MySQL
Mệnh đề GROUP BY trong MySQL

Chức năng của Mệnh đề GROUP BY trong MySQL

Mệnh đề GROUP BY trong MySQL được sử dụng để nhóm các hàng có cột giống nhau lại nhằm mục đích tính tổng(SUM), số cao nhất(MAX), trung bình(AVG), bạn có thể nhóm 1 cột hoặc nhiều cột, có thể dùng điều kiện HAVING cho nhóm.

Code Mệnh đề GROUP BY trong MySQL

select id_cha1,MAX(gia) as giacaonhat, SUM(gia) as tonggia, AVG(gia) as giatrungbinh from tb_sanpham where hienthi=1 GROUP BY id_cha1;
select id_cha2,id_cha1,MAX(gia) as giacaonhat, SUM(gia) as tonggia, AVG(gia) as giatrungbinh from tb_sanpham where hienthi=1 GROUP BY id_cha1,id_cha2;
select id_cha2,id_cha1,MAX(gia) as giacaonhat, SUM(gia) as tonggia, AVG(gia) as giatrungbinh from tb_sanpham where hienthi=1 GROUP BY id_cha1,id_cha2 HAVING tonggia<90000000;
<?php
   $dbhost = 'localhost';
   $dbuser = 'webmoi_userdata'; // Tên username
   $dbpass = 'xgZwEfQWE'; // Mật khẩu
   // Kết nối đến tên username
   $conn = mysql_connect($dbhost, $dbuser, $dbpass);
   if(! $conn ){
     die('Không kết nối được: ' . mysql_error());
   }
   // Chọn tên database
   mysql_select_db('webmoi_tendata');
   // Xét kiểu tiếng việt 
   mysql_query('SET NAMES "utf8"');
   // GROUP BY id_cha1
   echo "<b>GROUP BY id_cha1</b><br>";
   $sql ="select id_cha1,MAX(gia) as giacaonhat, SUM(gia) as tonggia, AVG(gia) as giatrungbinh from tb_sanpham where hienthi=1 GROUP BY id_cha1";
   $ketquamot = mysql_query($sql,$conn);
   if(!$ketquamot){
	  die('Không thể lấy dữ liệu: ' . mysql_error());  
   }
   // Dùng vòng lặp để lấy ra từng hàng trong bảng	
	while($row = mysql_fetch_array($ketquamot, MYSQL_ASSOC)){
		 echo "ID Cha cấp một: {$row['id_cha1']} <br> ".
		 "Giá cao nhất: ".number_format($row['giacaonhat'],0,"",".")." <br> ".
         "Tổng giá: ".number_format($row['tonggia'],0,"",".")." <br> ".
         "Giá trung bình : ".number_format($row['giatrungbinh'],0,"",".")." <br> ".
         "--------------------------------<br>";
   }
   // GROUP BY id_cha1,id_cha2
   echo "<b>GROUP BY id_cha1,id_cha2</b><br>";
   $sql ="select id_cha2,id_cha1,MAX(gia) as giacaonhat, SUM(gia) as tonggia, AVG(gia) as giatrungbinh from tb_sanpham where hienthi=1 GROUP BY id_cha1,id_cha2";
   $ketquahai = mysql_query($sql,$conn);
   if(!$ketquahai){
	  die('Không thể lấy dữ liệu: ' . mysql_error());  
   }
   // Dùng vòng lặp để lấy ra từng hàng trong bảng	
	while($row = mysql_fetch_array($ketquahai, MYSQL_ASSOC)){
		 echo "ID Cha cấp một: {$row['id_cha1']} <br> ".
		 "ID Cha cấp hai: {$row['id_cha2']} <br> ".
		 "Giá cao nhất: ".number_format($row['giacaonhat'],0,"",".")." <br> ".
         "Tổng giá: ".number_format($row['tonggia'],0,"",".")." <br> ".
         "Giá trung bình : ".number_format($row['giatrungbinh'],0,"",".")." <br> ".
         "--------------------------------<br>";
   }  
   // GROUP BY id_cha1,id_cha2, HAVING tonggia<90000000
   echo "<b>GROUP BY id_cha1,id_cha2, HAVING tonggia<90000000</b><br>";
   $sql ="select id_cha2,id_cha1,MAX(gia) as giacaonhat, SUM(gia) as tonggia, AVG(gia) as giatrungbinh from tb_sanpham where hienthi=1 GROUP BY id_cha1,id_cha2 HAVING tonggia<90000000";
   $ketquaba = mysql_query($sql,$conn);
   if(!$ketquaba){
	  die('Không thể lấy dữ liệu: ' . mysql_error());  
   }
   // Dùng vòng lặp để lấy ra từng hàng trong bảng	
	while($row = mysql_fetch_array($ketquaba, MYSQL_ASSOC)){
		 echo "ID Cha cấp một: {$row['id_cha1']} <br> ".
		 "ID Cha cấp hai: {$row['id_cha2']} <br> ".
		 "Giá cao nhất: ".number_format($row['giacaonhat'],0,"",".")." <br> ".
         "Tổng giá: ".number_format($row['tonggia'],0,"",".")." <br> ".
         "Giá trung bình : ".number_format($row['giatrungbinh'],0,"",".")." <br> ".
         "--------------------------------<br>";
   }
   // Đóng kết nối database
   mysql_close($conn);
?>

Kết quả:

GROUP BY id_cha1
ID Cha cấp một: 1
Giá cao nhất: 55.000.000
Tổng giá: 154.550.000
Giá trung bình : 38.637.500
--------------------------------
ID Cha cấp một: 2
Giá cao nhất: 3.400.000
Tổng giá: 6.100.000
Giá trung bình : 3.050.000
--------------------------------
GROUP BY id_cha1,id_cha2
ID Cha cấp một: 1
ID Cha cấp hai: 4
Giá cao nhất: 55.000.000
Tổng giá: 99.550.000
Giá trung bình : 49.775.000
--------------------------------
ID Cha cấp một: 1
ID Cha cấp hai: 5
Giá cao nhất: 30.000.000
Tổng giá: 55.000.000
Giá trung bình : 27.500.000
--------------------------------
ID Cha cấp một: 2
ID Cha cấp hai: 6
Giá cao nhất: 3.400.000
Tổng giá: 6.100.000
Giá trung bình : 3.050.000
--------------------------------
GROUP BY id_cha1,id_cha2, HAVING tonggia<90000000
ID Cha cấp một: 1
ID Cha cấp hai: 5
Giá cao nhất: 30.000.000
Tổng giá: 55.000.000
Giá trung bình : 27.500.000
--------------------------------
ID Cha cấp một: 2
ID Cha cấp hai: 6
Giá cao nhất: 3.400.000
Tổng giá: 6.100.000
Giá trung bình : 3.050.000
--------------------------------

Những lỗi thường gặp khi sử dụng GROUP BY trong MySQL

Khi mới làm quen với GROUP BY, kết quả truy vấn đôi khi không giống như mong muốn dù cú pháp vẫn gần đúng. Phần lớn vấn đề đến từ việc chọn cột, đặt điều kiện lọc hoặc nhóm dữ liệu chưa phù hợp.

Chọn cột không phù hợp với GROUP BY

Khi sử dụng GROUP BY, các cột xuất hiện trong SELECT cần được đưa vào nhóm hoặc sử dụng cùng một hàm tổng hợp như COUNT(), SUM(), AVG(), MIN()MAX(). Nếu lấy thêm một cột không thuộc nhóm mà không có hàm tổng hợp, MySQL có thể báo lỗi, đặc biệt khi chế độ ONLY_FULL_GROUP_BY được bật.

SELECT department_id, employee_name, COUNT(*) AS total
FROM employees
GROUP BY department_id;

Trong ví dụ trên, department_id được dùng để nhóm nhưng employee_name lại không được nhóm hoặc tổng hợp. Cách viết an toàn hơn là chỉ lấy những dữ liệu thực sự cần thiết cho kết quả thống kê.

SELECT department_id, COUNT(*) AS total
FROM employees
GROUP BY department_id;

Phân biệt WHERE và HAVING khi lọc dữ liệu

WHERE dùng để lọc từng dòng dữ liệu trước khi thực hiện nhóm, còn HAVING dùng để lọc kết quả sau khi các dòng đã được gom nhóm. Nhầm hai mệnh đề này là lỗi khá phổ biến khi làm việc với các hàm tổng hợp.

SELECT category_id, COUNT(*) AS total
FROM products
WHERE status = 'active'
GROUP BY category_id
HAVING COUNT(*) >= 10;

Trong truy vấn trên, WHERE loại bỏ sản phẩm không hoạt động trước khi nhóm. Sau đó, HAVING chỉ giữ lại những nhóm có ít nhất 10 sản phẩm. Nếu điều kiện liên quan đến kết quả của COUNT(), SUM() hoặc hàm tổng hợp khác thì nên xem xét sử dụng HAVING.

GROUP BY nhiều cột và kết quả dễ nhầm lẫn

Khi thêm nhiều cột vào GROUP BY, MySQL sẽ tạo nhóm dựa trên tổ hợp giá trị của tất cả các cột đó. Vì vậy, thêm một cột vào nhóm có thể làm số lượng nhóm tăng lên đáng kể.

SELECT category_id, status, COUNT(*) AS total
FROM products
GROUP BY category_id, status;

Ở đây, sản phẩm được phân thành từng nhóm theo cả category_idstatus. Hai sản phẩm cùng danh mục nhưng khác trạng thái sẽ nằm ở hai nhóm riêng biệt. Trước khi thêm cột vào GROUP BY, nên xác định rõ dữ liệu muốn thống kê theo một tiêu chí hay theo sự kết hợp của nhiều tiêu chí.

Lời kết

Cảm ơn các bạn đã tham khảo bài viết Mệnh đề GROUP BY trong MySQL.

Tải file database .sql về nếu muốn kiểm tra hoặc thực hành Tải về.

  • 0 Bình luận
Trần Thị Vân | Content Creator Web Mới
Trần Thị Vân
Trần Thị Vân là Content Creator tại Web Mới, phụ trách nghiên cứu, biên soạn nội dung và chia sẻ kiến thức về website, SEO, lập trình cùng các xu hướng công nghệ
Đánh giá
Chia sẻ nội dung đánh giá của bạn về Mệnh đề GROUP BY trong MySQL
Email, Điện thoại của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *
Đánh giá của bạn
Tên *
Email
Số điện thoại *
Bình luận, Hỏi đáp
Yêu Cầu Báo Giá
Gửi trang web mẫu cần làm theo, chúng tôi sẽ báo giá đến bạn từ Email (tanlucit09@gmail.com - Bùi Tấn Lực) hoặc Zalo (Lực IT - 0398259259) !