数据库笔记-查询处理

逻辑查询处理

1
2
3
4
5
6
7
8
9
10
(8) SELECT (9) DISTINCT <select_list>
(1) FROM <left_table>
(3) <join_type> JOIN <right_table>
(2) ON <join_condition>
(4) WHERE <where_condition>
(5) GROUP BY <group_by_list>
(6) WITH {CUBE|ROLLUP}
(7)HAVING <having_condition>
(10) ORDER BY <order_by_list>
(11) LIMIT <limit_number>

1.执行笛卡尔积

FROM子句前后的两张表进行笛卡尔积操作,也叫交叉连接(Cross Join)。

2.ON过滤器

NULL值:UNKNOWN,即表示未知的。即,NULL和NULL是不相等的,NULL与任何值也不相等。

在以下连个特殊条件下,两个NULL值比较是相等的:

  1. GROUP BY 子句把所有NULL值分到同一组;
  2. ORDER BY 子句把所有NULL值排列在一起。

3.添加外部行

只在连接类型为OUTER JOIN时才发生,如LEFT OUT JOIN、RIGHT OUTER JOIN和FULL OUTER JOIN。通常省略了OUTER关键字。

4.WHERE过滤器

有两种过滤不被允许:

  1. 由于数据还没有分组,因此现在还不能在WHERE过滤器中使用where_condition=MIN(col)这类对统计的过滤;
  2. 由于没有进行列的选取操作,因此在SELECT中使用列的别名不被允许。

eg.

1
2
3
4
mysql> SELECT custom_id, COUNT(custom_id)
-> FROM orders
-> WHERE COUNT(custom_id) < 2;
ERROR 1111(HY000):Invalid use of group function

SELECT 操作的执行顺序排在WHERE条件之后

1
2
3
4
5
mysql> SELECT order_id AS o, custom_id AS c
-> FROM orders
-> WHERE c = '163';
ERROR 1054(42S22):Unknown colum 'c' in 'where clause'
//修改为:WHERE c.company = '163'

ON过滤器和WHERE过滤器的差别

类型 ON过滤器 WHERE过滤器
OUTER JOIN 会保留表中被ON条件过滤掉的数据 不保留

对于INNER JOIN两者无差别,因为没有添加外部行操作

5.分组

6.ROLLUP或CUBE

指定ROLLUP选项会添加额外的记录到虚拟表;
MYSQL并不支持CUBE。

7.HAVING过滤器

HVAING子查询不能做分组的聚合函数,如下错误示范

1
HAVING COUNT(SELECT ...) < 2

8.SELECT

列的别名不能在SELECT中的其他别名表达式中使用,如下错误示范

1
2
mysql> SELECT order_id AS o, o+1 AS n FROM orders;
ERROR 1054(42S22):Unknown column 'o' in 'field list'

9.DISTINCT

对进行DISTINCT操作的列增加了唯一的索引,以此来去除重复的数据。

对于使用了 GROUP BY 的查询,再使用DISTINCT是多余的,因为已经分组了,不会移除任何行。

10.ORDER BY

无论是InnoDB存储引擎还是MyISAM存储引擎,对于没有使用ORDER BY子句的选择查询,其结果永远不会是按照主键顺序进行排序的。因为没有ORDER BY子句的查询只代表从集合中查询数据,而集合是没有顺序概念的。

NULL值在ORDER BY中被视为最小值。

11.LIMIT

表示从第n条记录开始选择m条记录

1
LIMIT n, m

子查询

概述

子查询是指一个SELECT语句中嵌套另一个SELECT语句。如:

1
SELECT * FROM t1 WHERE column1 = (SELECET column2 FROM t2 );

子查询的限制:

  1. 外部语句必须是以下语句之一:SELECT、INSERT、UPDATE、DELETE、SET或DO。
  2. 目前用户不能既在一个子查询中修改一个表,又在同一个表中进行选择,虽然这样的操作可用于DELETE、INSERT、REPLACE和UPDATE语句中,但是对于子查询不可以同时进行操作。

常见的子查询

可以使用如下的操作符:

1
2
3
4
5
6
=
>
<
>=
<=
<>

不能使用JOIN来完成的操作,常用子查询进行,例如表t1中有些值与表t2中的最大值相等。

1
2
SELECT col1 FROM t1
WHERE col1 = (SELECT MAX(col2) FROM t2);

又如涉及表的统计时候,也不能用JOIN来得到结果。表t1中的有些行含有的值会在给定的列中出现两次,该例子可以查找出所有的这些行。

1
2
SELECT * FROM t1 AS t
WHERE 2 = (SELEECT COUNT(*) FROM t WHERE t1.id = t.id);

使用ANY、IN和SOME进行子查询

ANY关键字必须与一个比较操作符一起使用,SOME是ANY的别名。
ANY关键字的意思:“对于子查询返回的列中任一数值,如果比较结果为TRUE, 则返回TRUE”。如:

1
SELECT col FROM t WHERE col > ANY(SELECT col FROM t2)

关键字IN是“=ANY”的别名。

使用ALL进行子查询