在利用mysql时,有时须要查询出某个字段不重复的记录,虽然mysql供应 有distinct这个关键字来过滤掉多余的重复记录只保留一条,但每每只用它来返回不重复记录的条数,而不是用它来返回不重记录的所有值。其缘故原由是 distinct只能返回它的目标字段,而无法返回其它字段,这个问题让我困扰了良久,用distinct不能办理的话,我只有用二重循环查询来办理,而 这样对付一个数据量非常大的站来说,无疑是会直接影响到效率的。以是我花了很多韶光来研究这个问题,网上也查不到办理方案
下面先来看看例子:
table
id name
1 a
2 b
3 c
4 c
5 b
库构造大概这样,这只是一个大略的例子,实际情形会繁芜得多。
比如我想用一条语句查询得到name不重复的所有数据,那就必须利用distinct去掉多余的重复记录。
select distinct name from table
得到的结果是:
name
a
b
c
彷佛达到效果了,可是,我想要得到的是id值呢?改一下查询语句吧:
select distinct name, id from table
结果会是:
id name
1 a
2 b
3 c
4 c
5 b
distinct怎么没起浸染?浸染是起了的,不过他同时浸染了两个字段,也便是必须得id与name都相同的才会被打消。。。。。。。
我们再改改查询语句:
select id, distinct name from table
很遗憾,除了缺点信息你什么也得不到,distinct必须放在开头。难到不能把distinct放到where条件里?能,还是报错。。。。。。。
很麻烦吧?确实,费尽心思都没能办理这个问题。
用count函数一试,成功,我。。。。。。。想哭啊,费了这么多工夫。。。。。。。。原来就这么大略。。。。。。
现在将完全语句放出:
select , count(distinct name) from table group by name
结果:
id name count(distinct name)
1 a 1
2 b 1
3 c 1
末了一项是多余的,不用管就行了,目的达到。。。。。
唉,原来mysql这么笨,轻轻一下就把他骗过去了,忧郁也就我吧(对了,还有容容那家伙),现在拿出来希望大家不要被这问题折腾。
哦,对,再顺便说一句,group by
group by 用法解析
group by语法可以根据给天命据列的每个成员对查询结果进行分组统计,终极得到一个分组汇总表。
SELECT子句中的列名必须为分组列或列函数。列函数对付GROUP BY子句定义的每个组各返回一个结果。
某个员工信息表构造和数据如下:
id name dept salary edlevel hiredate
1 张三 开拓部 2000 3 2009-10-11
2 李四 开拓部 2500 3 2009-10-01
3 王五 设计部 2600 5 2010-10-02
4 王六 设计部 2300 4 2010-10-03
5 马七 设计部 2100 4 2010-10-06
6 赵八 发卖部 3000 5 2010-10-05
7 钱九 发卖部 3100 7 2010-10-07
8 孙十 发卖部 3500 7 2010-10-06
例如,我想列出每个部门最高薪水的结果,sql语句如下:
SELECT DEPT, MAX(SALARY) AS MAXIMUM
FROM STAFF
GROUP BY DEPT
查询结果如下:
DEPT MAXIMUM
开拓部 2500
设计部 2600
发卖部 3500
阐明一下这个结果:
1、知足“SELECT子句中的列名必须为分组列或列函数”,由于SELECT有GROUP BY DEPT中包含的列DEPT。
2、“列函数对付GROUP BY子句定义的每个组各返回一个结果”,根据部门分组,对每个部门返回一个结果,便是每个部门的最高薪水。
把稳:打算的是每个部门(由 GROUP BY 子句定义的组)而不是全体公司的 MAX(SALARY)。
例如,查询每个部门的总的薪水数
SELECT DEPT, sum( SALARY ) AS total
FROM STAFF
GROUP BY DEPT
查询结果如下:
DEPT total
开拓部 4500
设计部 7000
发卖部 9600
将 WHERE 子句与 GROUP BY 子句一起利用
分组查询可以在形成组和打算列函数之前具有肃清非限定行的标准 WHERE 子句。必须在GROUP BY 子句之前指定 WHERE 子句。
例如,查询公司2010年入职的各个部门每个级别里的最高薪水
SELECT DEPT, EDLEVEL, MAX( SALARY ) AS MAXIMUM
FROM staff
WHERE HIREDATE > '2010-01-01'
GROUP BY DEPT, EDLEVEL
ORDER BY DEPT, EDLEVEL
查询结果如下:
DEPT EDLEVEL MAXIMUM
设计部 4 2300
设计部 5 2600
发卖部 5 3000
发卖部 7 3500
把稳:在SELECT语句中指定的每个列名也在GROUP BY子句中提到。未在这两个地方提到的列名将产生缺点。
GROUP BY子句对DEPT和EDLEVEL的每个唯一组合各返回一行。
在GROUP BY子句之后利用HAVING子句
可运用限定条件进行分组,以便系统仅对知足条件的组返回结果。为此,在GROUP BY子句后面包含一个HAVING子句。HAVING子句可包含一个或多个用AND和OR连接的谓词。每个谓词将组特性(如AVG(SALARY))与下列之一进行比较:
例如:探求雇员数超过2个的部门的最高和最低薪水:
SELECT DEPT, MAX( SALARY ) AS MAXIMUM, MIN( SALARY ) AS MINIMUM
FROM staff
GROUP BY DEPT
HAVING COUNT( ) >2
ORDER BY DEPT
查询结果如下:
DEPT MAXIMUM MINIMUM
设计部 2600 2100
发卖部 3500 3000
例如:探求雇员均匀人为大于3000的部门的最高和最低薪水:
SELECT DEPT, MAX( SALARY ) AS MAXIMUM, MIN( SALARY ) AS MINIMUM
FROM staff
GROUP BY DEPT
HAVING AVG( SALARY ) >3000
ORDER BY DEPT
查询结果如下:
DEPT MAXIMUM MINIMUM
发卖部 3500 3000