(本文中SQL语句均在Mysql v5.1中验证)
group by 是按照表中的某些个属性对表进行分组,然后再用having子句对得到的分组进行筛选,最后使用
order by 则是对已经分好的组按照某种规则进行排序,如果 order by 后使用了聚集函数,则是对这个
组中的所有行进行计算(如下面的 max(date)),然后按计算的结果再对各个组进行 order by 操作,而不是
在分组内进行 order by 的排序。
个人感觉,在一个包含有group by的SQL语句中,select 以及 order by(如果有的话)后面的字段,
要么是包含在了 group by 当中,要么就是被使用了聚集函数,如 sum,max等。
mysql> select * from t;
+------+------------+-------+---------------------+
| id | name | count | date |
+------+------------+-------+---------------------+
| 1 | apple | 10 | 2011-07-01 00:00:00 |
| 1 | orange | 20 | 2011-07-02 00:00:00 |
| 1 | banana | 15 | 2011-07-03 00:00:00 |
| 2 | white vege | 12 | 2011-07-01 00:00:00 |
| 2 | blue vege | 19 | 2011-07-02 00:00:00 |
| 2 | red vege | 18 | 2011-07-02 00:00:00 |
+------+------------+-------+---------------------+
6 rows in set (0.01 sec)
mysql> select id, max(date) from t group by id order by max(date);
+------+---------------------+
| id | max(date) |
+------+---------------------+
| 2 | 2011-07-02 00:00:00 |
| 1 | 2011-07-03 00:00:00 |
+------+---------------------+
2 rows in set (0.02 sec)
此条语句就是先根据id分成两组,然后在各组中分别求得其max(date),再根据max(date)值对两组进行升序排序。
mysql> select id, date from t group by id;
+------+---------------------+
| id | date |
+------+---------------------+
| 1 | 2011-07-01 00:00:00 |
| 2 | 2011-07-01 00:00:00 |
+------+---------------------+
2 rows in set (0.02 sec)
此条语句的select后面就跟随了一个date属性,它即没有被作用于聚集函数,又没有被用在group by后的分组,
所以得到的结果没有什么意义,仅仅是把每组的第一条数据输出而已。
另外关于 group by 和 having 的分析可参考:http://www.cnblogs.com/gaiyang/archive/2011/04/01/2002452.html
把用到的部分摘录如下:
Group by与having理解
注意:select 后的字段,必须要么包含在group by中,要么包含在having 后的聚合函数里。
1. GROUP BY 是分组查询, 一般 GROUP BY 是和聚合函数配合使用
group by 有一个原则,就是 select 后面的所有列中,没有使用聚合函数的列,必须出现在 group by 后面(重要)
例如,有如下数据库表:
A B
1 abc
1 bcd
1 asdfg
如果有如下查询语句(该语句是错误的,原因见前面的原则)select A,B from table group by A
该查询语句的意图是想得到如下结果(当然只是一相情愿)
A B
abc
1 bcd
asdfg
右边3条如何变成一条,所以需要用到聚合函数,如下(下面是正确的写法):
select A,count(B) as 数量 from table group by A
这样的结果就是
A 数量
1 3
2. Having
where 子句的作用是在对查询结果进行分组前,将不符合where条件的行去掉,即在分组之前过滤数据,条件中不能包含聚组函数,使用where条件显示特定的行。
having 子句的作用是筛选满足条件的组,即在分组之后过滤数据,条件中经常包含聚组函数,使用having 条件显示特定的组,也可以使用多个分组标准进行分组。
having 子句被限制子已经在SELECT语句中定义的列和聚合表达式上。通常,你需要通过在HAVING子句中重复聚合函数表达式来引用聚合值,就如你在SELECT语句中做的那样。例如:
SELECT A COUNT(B) FROM TABLE GROUP BY A HAVING COUNT(B)>2
<font color="red">加颜色</font>
<b>字体加粗</b>
<i>斜体字</i>
group by 是按照表中的某些个属性对表进行分组,然后再用having子句对得到的分组进行筛选,最后使用
order by 则是对已经分好的组按照某种规则进行排序,如果 order by 后使用了聚集函数,则是对这个
组中的所有行进行计算(如下面的 max(date)),然后按计算的结果再对各个组进行 order by 操作,而不是
在分组内进行 order by 的排序。
个人感觉,在一个包含有group by的SQL语句中,select 以及 order by(如果有的话)后面的字段,
要么是包含在了 group by 当中,要么就是被使用了聚集函数,如 sum,max等。
mysql> select * from t;
+------+------------+-------+---------------------+
| id | name | count | date |
+------+------------+-------+---------------------+
| 1 | apple | 10 | 2011-07-01 00:00:00 |
| 1 | orange | 20 | 2011-07-02 00:00:00 |
| 1 | banana | 15 | 2011-07-03 00:00:00 |
| 2 | white vege | 12 | 2011-07-01 00:00:00 |
| 2 | blue vege | 19 | 2011-07-02 00:00:00 |
| 2 | red vege | 18 | 2011-07-02 00:00:00 |
+------+------------+-------+---------------------+
6 rows in set (0.01 sec)
mysql> select id, max(date) from t group by id order by max(date);
+------+---------------------+
| id | max(date) |
+------+---------------------+
| 2 | 2011-07-02 00:00:00 |
| 1 | 2011-07-03 00:00:00 |
+------+---------------------+
2 rows in set (0.02 sec)
此条语句就是先根据id分成两组,然后在各组中分别求得其max(date),再根据max(date)值对两组进行升序排序。
mysql> select id, date from t group by id;
+------+---------------------+
| id | date |
+------+---------------------+
| 1 | 2011-07-01 00:00:00 |
| 2 | 2011-07-01 00:00:00 |
+------+---------------------+
2 rows in set (0.02 sec)
此条语句的select后面就跟随了一个date属性,它即没有被作用于聚集函数,又没有被用在group by后的分组,
所以得到的结果没有什么意义,仅仅是把每组的第一条数据输出而已。
另外关于 group by 和 having 的分析可参考:http://www.cnblogs.com/gaiyang/archive/2011/04/01/2002452.html
把用到的部分摘录如下:
Group by与having理解
注意:select 后的字段,必须要么包含在group by中,要么包含在having 后的聚合函数里。
1. GROUP BY 是分组查询, 一般 GROUP BY 是和聚合函数配合使用
group by 有一个原则,就是 select 后面的所有列中,没有使用聚合函数的列,必须出现在 group by 后面(重要)
例如,有如下数据库表:
A B
1 abc
1 bcd
1 asdfg
如果有如下查询语句(该语句是错误的,原因见前面的原则)select A,B from table group by A
该查询语句的意图是想得到如下结果(当然只是一相情愿)
A B
abc
1 bcd
asdfg
右边3条如何变成一条,所以需要用到聚合函数,如下(下面是正确的写法):
select A,count(B) as 数量 from table group by A
这样的结果就是
A 数量
1 3
2. Having
where 子句的作用是在对查询结果进行分组前,将不符合where条件的行去掉,即在分组之前过滤数据,条件中不能包含聚组函数,使用where条件显示特定的行。
having 子句的作用是筛选满足条件的组,即在分组之后过滤数据,条件中经常包含聚组函数,使用having 条件显示特定的组,也可以使用多个分组标准进行分组。
having 子句被限制子已经在SELECT语句中定义的列和聚合表达式上。通常,你需要通过在HAVING子句中重复聚合函数表达式来引用聚合值,就如你在SELECT语句中做的那样。例如:
SELECT A COUNT(B) FROM TABLE GROUP BY A HAVING COUNT(B)>2
<font color="red">加颜色</font>
<b>字体加粗</b>
<i>斜体字</i>