Monday, July 4, 2016

数据库手札2 16/7/4





使用WHERE子句和GROUP BY 子句进行聚合处理
SELECT <列名1>, <列名2>, <列名3> ……
FROM <表名>
WHERE
GROUP BY <列名1>, <列名2>, <列名3> ……;
Eg:
SELECT shiire_tanka, COUNT(*)
FROM Shohin
WHERE shohin_bunrui = ‘衣服
GROUP BY shiire_tanka;
GROUP BY WHERE并用时,SELECT语句的执行顺序如下:
FROM->WHERE->GROUP BY->SELECT
这与3-2中提到的书写语句的顺序(SELECT-> FROM->WHERE->GROUP BY)是不同的

**TIP: 与聚合函数和GROUP BY子句有关的常见错误:
常见错误1. SELECT子句中书写了多余的列
原因是:在使用COUNT这样的聚合函数时,SELECT子句中的元素有严格的限制。在使用聚合函数时,SELECT子句中只能存在以下三种元素:
1.       常数
2.       聚合函数
3.       GROUP BY 子句中指定的列名(也就是聚合键)
而我们经常容易犯的错误是: 把聚合键之外的列名写在SELECT子句中

常见错误2. GROUP BY子句中写了列的别名
原因是:SELECT子句中的项目可以通过AS关键字来指定别名,但是在GROUP BY子句中是不能使用别名的。
错误示例:
SELECT shohin_bunrui AS sb, COUNT(*)
  FROM Shohin
GROUP BY sb;
会有这些错误的内在原因其实就是子句的执行顺序。

常见错误3. 以为GROUP BY子句的结果是排序的
     实际上GROUP BY子句的结果的显示是无序、完全偶然的。如果想要按照某种特定顺序进行排序的话,需要在SELECT语句中进行指定。

常见错误4. WHERE子句中使用聚合函数
错误示例:
SELECT shohin_bunrui, COUNT(*)
  FROM Shohin
WHERE COUNT(*) = 2
GROUP BY shohin_bunrui;
实际上,只有SELECT子句、HAVING子句和ORDER BY子句中能够使用COUNT等聚合函数。

3-3 为聚合结果指定条件
HAVING子句
WHERE子句只能指定记录(行)的条件,而不能用来指定组的条件。因此对集合指定条件就需要HAVING子句。
SELECT <列名1>, <列名2>, <列名3>, ……
FROM <表名>
GROUP BY <列名1>, <列名2>, <列名3>, ……
HAVING <分组结果对应的条件>
HAVING子句必须写在GROUP BY子句之后。其在DBMS内部的执行顺序也排在GROUP BY子句之后。所以使用HAVING子句时SELECT语句的顺序:
SELECT->FROM->WHERE->GROUP BY->HAVING

Eg: 从通过商品种类进行聚合分组后的结果中,取出“包含数据的行数为2行”的组
SELECT shohin_bunrui, COUNT(*)
FROM Shohin
GROUP BY shohin_bunrui
HAVING COUNT(*) = 2;

**HAVING 子句和包含GROUP BY 子句时的SELECT子句一样,能够使用的要素有一定的限制。限制的内容也是完全相同的:
1.       常数
2.       聚合函数
3.       GROUP BY 子句中指定的列名(也就是聚合键)

** 对于聚合键所对应的条件,它既可以写在HAVING子句中,也可以写在WHERE子句中的这种情况,写在WHERE子句中更合适。原因有两个:其一,WHEREHAVING两者含义不同,WHERE子句 = 指定行对应的条件,HAVING子句 = 指定组所对应的条件。 其次,WHERE子句的执行速度较HAVING子句要更快一些。



3-4 对查询结果进行排序
   ORDER BY子句
   通常,从表中抽取数据时,如果没有特别指定顺序,最终排列顺序便无从得知。为了避免混乱的结果,便需要通过SELECT语句末尾添加ORDER BY 子句来明确指定排列顺序。
语法如下:
SELECT <列名1>, <列名2>, <列名3>, ……
FROM <表名>;
ORDER BY <排序基准列1>, <排序基准列2>, ……
Eg:
SELECT shohin_id, shohin_mei, hanbai_tanka, shiire_tanka
FROM Shohin
ORDER BY hanbai_tanka;

不论何种情况,ORDER BY子句都需要写在SELECT语句的末尾。这是因为对数据行进行排列的操作必须在结果即将返回时执行。
使用HAVING子句时SELECT语句的顺序:
1.SELECT子句->2.FROM子句->3.WHERE子句->4.GROUP BY子句->5.HAVING子句->6.ORDER BY子句

指定升序或降序
ORDER BY列名后加上ASC/DESC关键字。未指定ORDER BY子句中排列顺序时会默认使用升序进行排列。
ASC
Ascendent 上升的
DESC
Descendent  下降的

指定多个排序键
     如果指定了多个排序键,那么会优先使用左侧的键,当该列存在相同值时,会接着参考右侧的键。
Eg:
SELECT shohin_id, shohin_mei, hanbai_tanka, shiire_tanka
FROM Shohin
ORDER BY hanbai_tanka, shohin_id;

**当使用含有NULL的列作为排序键时,NULL会在结果的开头或末尾汇总显示。

ORDER BY子句中可以使用SELECT子句中定义的别名
    GROUP BY子句中不允许使用别名,为什么ORDER BY中可以呢?这是因为SELECT子句的执行顺序在GROUP BY子句之后,在ORDER BY子句之前。
Eg:
SELECT shohin_id AS id, shohin_mei, hanbai_tanka AS ht, shiire_tanka
FROM Shohin
ORDER BY ht, id;

**ORDER BY子句中可以使用表中的列(无论SELECT子句中是否使用)和聚合函数。
**ORDER BY子句中还可以使用列编号,但是最好不这么用。因为代码阅读起来比较困难,并且该排序功能将来可能会被删除(SQL-92中明确指出)。

No comments:

Post a Comment