数据库中group by和having语法使用是什么样的
创始人
2024-12-21 02:22:14
0次

有个朋友问我一个返话费的问题,大概意思是这样的:只需把表deal中所有手机用户某天充值两次以上且总金额超过50的用户充值记录查询出来,至于怎么进行返话费那不是重点。

先看看group by的语法:

SELECT column1, SUM(column2) FROM "list-of-tables" GROUP BY "column-list"; 

GROUP BY子句将集中所有的行在一起,它包含了指定列的数据以及允许合计函数来计算一个或者多个列。

假设我们将从员工表employee表中搜索每个部门中工资最高的薪水,可以使用以下的SQL语句:

SELECT max(salary), dept FROM employee GROUP BY dept; 

这条语句将在每一个单独的部门中选择工资最高的工资,结果将他们的salary和dept返回。

    group by 顾名思义就是按照xxx进行分组,它必须有“聚合函数”来配合才能使用,使用时至少需要一个分组标识字段。

    聚合函数有:sum()、count()、avg()等,使用group by目的就是要将数据分组进行汇总操作。

    例如对员工表的操作:

select dept_id,count(emp_id),sum(salary) form employee  group by dept_id; 

    这样的运行结果就是以“dept_id”为分类标志统计各单位的职工人数和工资总额。

再看看having的语法:

SELECT column1, SUM(column2) FROM “list-of-tables” GROUP BY “column-list” HAVING “condition”; 

这个HAVING子句的作用就是为每一个组指定条件,像where指定条件一样,也就是说,可以根据你指定的条件来选择行。如果你要使用HAVING子句的话,它必须处在GROUP BY子句之后。

    例如还是对员工表的操作:

SELECT dept_id, avg(sal) FROM employee GROUP BY dept_id HAVING avg(salary) >= 4000; 

    这样的运行结果就是以“dept_id”为分类标志统计各单位的职工人数和工资平均数且工资平均数大于4000。

下面开始我们的返话费查询功能的实现:

话费表deal字段有这些:

sell_no:订单编号

name:用户名

phone:用户手机号

amount:充值金额

date:充值日期

上边就这些有效字段,假如数据(数据纯属虚构,如有*,纯是巧合)如下:

sell_no             name         phone               amount      date 

00000000001         李晓红       15822533496         50          2011-10-23 08:09:23 

00000000002         李晓红       15822533496         60          2011-10-24 08:15:34 

00000000003         李晓红       15822533496         30          2011-10-24 12:20:56 

00000000004         杨 轩        18200000000         100         2011-10-24 07:59:43 

00000000005         杨 轩        18200000000         200         2011-10-24 10:11:11 

00000000006         柳梦璃       18211111111         50          2011-10-24 09:09:46 

00000000007         韩菱纱       18222222222         50          2011-10-24 08:09:45 

00000000008         云天河       18333333333         50          2011-10-24 08:09:25 

把以上数据当天(2011-10-24)交过两次话费,而且总金额大于50的数据取出来,要取的结果如下:

00000000002         李晓红       15822533496         60          2011-10-24 08:15:34 

00000000003         李晓红       15822533496         30          2011-10-24 12:20:56 

00000000004         杨 轩        18200000000         100         2011-10-24 07:59:43 

00000000005         杨 轩        18200000000         200         2011-10-24 10:11:11 

因为今天(2011-10-24)李晓红和杨轩交过两次以上话费,而且总金额大于50,所以有他们的数据,而柳梦璃,韩菱纱,云天河只交过一次,所以没他们的数据。

我的处理思路大概是这样的,先把当天日期的记录用group by进行手机号分组即一个手机号为一组,接着用having子句进行过滤,把交过两次话费且话费总金额大于50的手机号查出来,最后用手机号和日期条件组合查询就能完成数据的查询,具体如下。

    注意日期处理细节,要查询的某一天(yyyy-MM-dd)的所有记录是这样处理的:

SELECT date_format(date,'%Y-%m-%d') from deal; 

    查询出符合条件(交过两次以上话费,而且总金额大于50)的手机号:

select phone from deal where date_format(date,'%Y-%m-%d')="2011-10-24" group by phone having count(phone)>1 and sum(amount)>50; 

    结合手机号和日期查询出最终记录:

select * from deal where date_format(date,'%Y-%m-%d')="2011-10-24" and phone in  

  (select phone from deal where date_format(date,'%Y-%m-%d')="2011-10-24"  

   group by phone having count(phone)>1 and sum(amount)>50) order by phone; 

    里边嵌套了一个select语句,感觉效率低点了,谁有更高效的方法不?

附数据建库sql代码:

create database if not exists `phone_deal`; 

USE `phone_deal`; 

DROP TABLE IF EXISTS `deal`; 

CREATE TABLE `deal` ( 

  `sell_no` varchar(100) NOT NULL, 

  `name` varchar(100) default NULL, 

  `phone` varchar(100) default NULL, 

  `amount` decimal(10,0) default NULL, 

  `date` datetime default NULL, 

  PRIMARY KEY  (`sell_no`) 

) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

insert  into `deal`(`sell_no`,`name`,`phone`,`amount`,`date`) values ('00001','李晓红','15822533496','60','2011-10-23 08:09:23'),('00002','李晓红','15822533496','50','2011-10-24 08:15:34'),('00003','李晓红','15822533496','40','2011-10-24 12:20:56'),('00004','杨轩','18210607179','100','2011-10-24 07:59:43'),('00005','杨轩','18210607179','50','2011-10-24 10:11:11'),('00006','柳梦璃','15822533492','1000','2011-10-24 09:09:46'),('00007','韩菱纱','15822533493','10000','2011-10-24 08:09:45'),('00008','云天河','15822533494','500','2011-10-24 08:09:25');   

相关内容

热门资讯

空调连续工作多久需要停机休息 空调连续工作的时间取决于多个因素,包括空调的型号、功率、使用环境和维护情况等。一般来说,空调可以连续...
空调哪个符号是除湿的 空调除湿功能通常用一个水滴形状的符号表示。不同品牌和型号的空调遥控器可能会有所差异,但一般来说,除湿...
格力空调多长时间加一次氟利昂 1、一般情况下,空调对氟利昂的使用量是非常小的,所以在空调使用了四年左右的时候再考虑加也没问题。2、...
空调用多长时间需要加氟一次 一般情况下是五年。当出现以下这几种情况时,空调才需要加氟。1、空调的室内机和室外机各有两个接口,当接...
格调生活·C标思享荟:卡萨帝在... 9月12日的郑州龙湖金融岛,夜风轻拂,灯光璀璨。“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑...
品牌价值破千亿、高端份额持续领... 9月12日,“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑州站”在郑州龙湖金融岛举办。2026...
空调主板坏了修800还是换新的 空调主板坏了是修还是换新,需要考虑多个因素,以下是一些建议:1. 维修成本:如果维修费用较低,比如 ...
空调开多久需要休息多长时间 问题:空调开多久需要休息多长时间回答:1、在使用空调的过程中,一般空调开7~8个小时左右需要休息2~...
中央空调多长时间清洗一次 1、一般空调开机前清洗一次即可,空调开机中间时段再清洗一次,空调关机时清洗一次,这样比较合理。2、空...
中央空调氟利昂多久加一次 看空调制热和制冷程度,很多人的观点认为氟利昂必须一年放一次,其实这个观点是错误的,理解上面有点偏差,...