Mệnh đề HAVING trong MySQL
Trần Thị Vân
- 1116
- 15/08/2025
Chức năng của Mệnh đề HAVING trong MySQL
Mệnh đề HAVING trong MySQL được sử dụng như mệnh đề WHERE nhưng nó chỉ dùng cho GROUP BY, đặt điều kiện cho các nhóm đã GROUP BY, trong mệnh đề HAVING kết hợp được các toán tử AND, OR,... như trong mệnh đề WHERE.
Code Mệnh đề HAVING trong MySQL
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,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";
$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> ".
"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 and tonggia>8000000
echo "<b>GROUP BY id_cha1,id_cha2, HAVING tonggia<90000000 and tonggia>8000000 </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 and tonggia>8000000";
$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_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
--------------------------------
GROUP BY id_cha1,id_cha2, HAVING tonggia<90000000 and tonggia>8000000
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
--------------------------------
Cách sử dụng HAVING trong MySQL hiệu quả
Để sử dụng HAVING đúng cách, cần xác định dữ liệu đang được lọc ở cấp độ nào. WHERE thường xử lý từng bản ghi trước khi nhóm dữ liệu, trong khi HAVING kiểm tra kết quả sau khi các nhóm đã được tạo. Sự khác biệt này đặc biệt quan trọng khi truy vấn có GROUP BY và các hàm tổng hợp.
Phân biệt HAVING và WHERE trong MySQL
WHERE dùng để loại bỏ những bản ghi không phù hợp trước khi MySQL thực hiện việc nhóm dữ liệu. Ngược lại, HAVING dùng để lọc các nhóm dựa trên kết quả tổng hợp như COUNT(), SUM() hoặc AVG().
Ví dụ, nếu chỉ muốn lấy các đơn hàng có trạng thái hoàn tất, có thể lọc ngay từ đầu bằng WHERE:
SELECT customer_id, COUNT(*) AS total_orders
FROM orders
WHERE status = 'completed'
GROUP BY customer_id;
Nếu muốn tìm những khách hàng có từ 5 đơn hàng hoàn tất trở lên, điều kiện liên quan đến kết quả COUNT() nên đặt trong HAVING:
SELECT customer_id, COUNT(*) AS total_orders
FROM orders
WHERE status = 'completed'
GROUP BY customer_id
HAVING COUNT(*) >= 5;
Có thể kết hợp cả hai: WHERE thu hẹp dữ liệu đầu vào, còn HAVING tiếp tục lọc kết quả của từng nhóm.
Kết hợp HAVING với các hàm tổng hợp
HAVING phát huy tác dụng rõ nhất khi đi cùng các hàm tổng hợp. Điều kiện có thể dựa trên số lượng bản ghi, tổng giá trị, giá trị trung bình hoặc giá trị lớn nhất, nhỏ nhất của từng nhóm.
Ví dụ, truy vấn dưới đây chỉ lấy những sản phẩm có tổng doanh thu từ 10.000.000 trở lên:
SELECT product_id, SUM(amount) AS total_amount
FROM order_details
GROUP BY product_id
HAVING SUM(amount) >= 10000000;
Cách viết này giúp điều kiện được áp dụng trực tiếp lên kết quả của từng nhóm, thay vì phải xử lý từng dòng dữ liệu riêng lẻ.
Kết hợp nhiều điều kiện trong HAVING
Một câu lệnh HAVING có thể chứa nhiều điều kiện bằng AND hoặc OR. Điều này phù hợp khi cần kiểm tra đồng thời nhiều tiêu chí của một nhóm dữ liệu.
Chẳng hạn, chỉ lấy những khách hàng có ít nhất 3 đơn hàng và tổng giá trị mua hàng đạt từ 5.000.000:
SELECT customer_id,
COUNT(*) AS total_orders,
SUM(amount) AS total_amount
FROM orders
GROUP BY customer_id
HAVING COUNT(*) >= 3
AND SUM(amount) >= 5000000;
Khi có nhiều điều kiện, nên viết rõ từng tiêu chí và đặt mỗi điều kiện trên một dòng để câu lệnh dễ kiểm tra, đặc biệt với những truy vấn có nhiều phép tính tổng hợp.
Những lỗi thường gặp khi sử dụng HAVING
- Dùng WHERE để lọc kết quả tổng hợp: các điều kiện như COUNT(*) > 5 hoặc SUM(amount) > 1000000 thường cần được đặt trong HAVING.
- Quên GROUP BY: khi muốn tính kết quả riêng cho từng nhóm, cần xác định rõ cột dùng để nhóm dữ liệu.
- Đặt điều kiện sai vị trí: điều kiện lọc bản ghi ban đầu nên ưu tiên WHERE, còn điều kiện dựa trên kết quả của nhóm nên dùng HAVING.
- Dùng quá nhiều điều kiện trong HAVING: nếu có thể lọc dữ liệu từ trước bằng WHERE, nên thực hiện ở bước đó để truy vấn dễ đọc và tránh xử lý những dữ liệu không cần thiết.
Một cách sử dụng hiệu quả là để WHERE giảm dữ liệu cần nhóm trước, sau đó dùng GROUP BY tạo các nhóm và cuối cùng dùng HAVING để chọn những nhóm đáp ứng yêu cầu.
Lời kết
Cảm ơn các bạn đã tham khảo bài viết Mệnh đề HAVING 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
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 *