程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> MYSQL數據庫 >> MySQL綜合教程 >> 數據庫中group by和having語法使用詳解

數據庫中group by和having語法使用詳解

編輯:MySQL綜合教程

 

   有個朋友問我一個返話費的問題,大概意思是這樣的:只需把表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)的所有記錄mysql是這樣處理的:

 

 

 

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. 下一頁:
Copyright © 程式師世界 All Rights Reserved