select语句完整语法
SELECT
{* | <字段列名>}
FROM <表 1>, <表 2>…
[where...] --指定结果需满足的条件
[GROUP by...] -- 指定结果按照那几个字段来分组
[HAVING] --过滤分组的记录必须满足的次要条件
[ORDER by...] --指定查询记录按一个过多个条件排序
[LIMIT[<offset>,] <row count>] -- 指定查询的记录从那一条到哪一条
select的完整执行顺序
-
FROM 执行笛卡尔积:
FROM 才是 SQL 语句执行的第一步,并非 SELECT 。对FROM子句中的前两个表执行笛卡尔积(交叉联接),生成虚拟表VT1,获取不同数据源的数据集。 -
应用ON过滤器:
对虚拟表VT1 应用ON筛选器,ON 中的逻辑表达式将应用到虚拟表 VT1中的各个行,筛选出满足ON 逻辑表达式的行,生成虚拟表 VT2 。 -
JOIN 添加外部行
如果指定了OUTER JOIN保留表中未找到匹配的行将作为外部行添加到虚拟表 VT2,生成虚拟表 VT3。保留表如下:
LEFT OUTER JOIN 把左表记为保留表
RIGHT OUTER JOIN 把右表记为保留表
FULL OUTER JOIN 把左右表都作为保留表
在虚拟表 VT2表的基础上添加保留表中被过滤条件过滤掉的数据,非保留表中的数据被赋予NULL值,最后生成虚拟表 VT3。
如果FROM子句包含两个以上的表,则对上一个联接生成的结果表和下一个表重复执行步骤1~3,直到处理完所有的表为止。 -
WHERE 应用WEHRE过滤器
对虚拟表 VT3应用WHERE筛选器。根据指定的条件对数据进行筛选,并把满足的数据插入虚拟表 VT4。
由于数据还没有分组,因此现在还不能在WHERE过滤器中使用聚合函数对分组统计的过滤。
同时,由于还没有进行列的选取操作,不能使用select中的别名。 -
GROUP BY 分组
1):按GROUP BY子句中的列/列表将虚拟表 VT4中的行唯一的值组合成为一组,生成虚拟表VT5。如果应用了GROUP BY,那么后面的所有步骤都只能得到的虚拟表VT5的列或者是聚合函数(count、sum、avg等)。原因在于最终的结果集中只为每个组包含一行。
2):同时,从这一步开始,后面的语句中都可以使用SELECT中的别名。 -
AGG_FUNC 计算聚合函数
计算 max 等聚合函数。SQL Aggregate 函数计算从列中取得的值,返回一个单一的值。 -
HAVING 应用HAVING过滤器
1):对虚拟表VT6应用HAVING筛选器。根据指定的条件对数据进行筛选,并把满足的数据插入虚拟表VT7。
2):HAVING 语句在SQL中的主要作用与WHERE语句作用是相同的,但是HAVING是过滤聚合值,在 SQL 中增加 HAVING 子句原因就是,WHERE 关键字无法与聚合函数一起使用,HAVING子句主要和GROUP BY子句配合使用。 -
SELECT 选出指定列
将虚拟表 VT7中的在SELECT中出现的列筛选出来,并对字段进行处理,计算SELECT子句中的表达式,产生虚拟表 VT8。 -
DISTINCT 行去重
将重复的行从虚拟表 VT8中移除,产生虚拟表 VT9。DISTINCT用来删除重复行,只保留唯一的。 -
ORDER BY 排列
将虚拟表 VT9中的行按ORDER BY 子句中的列/列表排序,生成游标 VC10 ; -
LIMIT/OFFSET 指定返回行
从VC10的开始处选择指定数量行,生成虚拟表 VT11,并返回调用者
MySQL七种join理论
原文链接:https://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins
- Inner JOIN
这是最简单、最容易理解的Join,也是最常见的。此查询将返回左表(表 A)中在右表(表 B)中具有匹配记录的所有记录。这个Join是这样写的:
SELECT <select_list>
FROM Table_A A
INNER JOIN Table_B B
ON A.Key = B.Key
- Left JOIN
此查询将返回左表(表 A)中的所有记录,无论这些记录中是否有任何记录在右表(表 B)中匹配。 它还将从正确的表中返回任何匹配的记录。 这个Join是这样写的:
SELECT <select_list>
FROM Table_A A
LEFT JOIN Table_B B
ON A.Key = B.Key
- Right JOIN
此查询将返回右表(表 B)中的所有记录,无论这些记录中是否有任何记录在左表(表 A)中匹配。它还将返回左表中的任何匹配记录。这个Join是这样写的:
SELECT <select_list>
FROM Table_A A
RIGHT JOIN Table_B B
ON A.Key = B.Key
- Outer JOIN
此联接也可以称为 FULL OUTER JOIN 或 FULL JOIN。 此查询将返回两个表中的所有记录,将左表(表 A)中的记录与右表(表 B)中的记录相匹配。 这个Join是这样写的:
SELECT <select_list>
FROM Table_A A
FULL OUTER JOIN Table_B B
ON A.Key = B.Key
- Left Excluding JOIN
This query will return all of the records in the left table (table A) that do not match any records in the right table (table B). This Join is written as follows:
SELECT <select_list>
FROM Table_A A
LEFT JOIN Table_B B
ON A.Key = B.Key
WHERE B.Key IS NULL
- Right Excluding JOIN
This query will return all of the records in the right table (table B) that do not match any records in the left table (table A). This Join is written as follows:
SELECT <select_list>
FROM Table_A A
RIGHT JOIN Table_B B
ON A.Key = B.Key
WHERE A.Key IS NULL
- Outer Excluding JOIN
此查询将返回左表(表 A)中的所有记录和右表(表 B)中所有不匹配的记录。 我还没有需要使用这种类型的 Join,但所有其他的,我都经常使用。 这个Join是这样写的:
SELECT <select_list>
FROM Table_A A
FULL OUTER JOIN Table_B B
ON A.Key = B.Key
WHERE A.Key IS NULL OR B.Key IS NULL