Sql 使用小结
一、Sql语句的执行顺序
(1)FROM:对FROM子句中的前两个表执行笛卡尔积(Cartesian product)(交叉联接),生成虚拟表VT1
(2)ON:对VT1应用ON筛选器。只有那些使<join_condition>为真的行才被插入VT2。
(3)OUTER(JOIN):如 果指定了OUTER JOIN(相对于CROSS JOIN 或(INNER JOIN),保留表(preserved table:左外部联接把左表标记为保留表,右外部联接把右表标记为保留表,完全外部联接把两个表都标记为保留表)中未找到匹配的行将作为外部行添加到 VT2,生成VT3.如果FROM子句包含两个以上的表,则对上一个联接生成的结果表和下一个表重复执行步骤1到步骤3,直到处理完所有的表为止。
(4)WHERE:对VT3应用WHERE筛选器。只有使<where_condition>为true的行才被插入VT4.
(5)GROUP BY:按GROUP BY子句中的列列表对VT4中的行分组,生成VT5.
(6)CUBE|ROLLUP:把超组(Suppergroups)插入VT5,生成VT6.
(7)HAVING:对VT6应用HAVING筛选器。只有使<having_condition>为true的组才会被插入VT7.
(8)SELECT:处理SELECT列表,产生VT8.
(9)DISTINCT:将重复的行从VT8中移除,产生VT9.
(10)ORDER BY:将VT9中的行按ORDER BY 子句中的列列表排序,生成游标(VC10).
(11)TOP:从VC10的开始处选择指定数量或比例的行,生成表VT11,并返回调用者。
二、Sql语句执行效率
1、从sql语句执行顺序得知,把有条件判断,有筛选的语句放在前面执行。比如可以先用where和on条件语句滤掉不需要的数据,用group by语句先去重,不要等最后再用distinct语句来去重。
2、sql语句的连表查询,无论是引用(where)还是join方式都会作笛卡尔乘积
笛卡尔乘积原理是选出符合匹配条件的所有表里的所有数据,所以在对匹配条件进行选择的时候一定要确保条件是一一对应的,否则连表后会得到两个表乘积后倍数的一个结果,与此同时,在连表后作count()运算时,结果就会扩大相应的倍数。
举例:
请看 "Persons" 表:
Id_P |
LastName |
FirstName |
Address |
City |
1 |
Adams |
John |
Oxford Street |
London |
2 |
Bush |
George |
Fifth Avenue |
New York |
3 |
Carter |
Thomas |
Changan Street |
Beijing |
请注意,"Id_P" 列是 Persons 表中的的主键。这意味着没有两行能够拥有相同的 Id_P。即使两个人的姓名完全相同,Id_P 也可以区分他们。
接下来请看 "Orders" 表:
Id_O |
OrderNo |
Id_P |
1 |
77895 |
3 |
2 |
44678 |
3 |
3 |
22456 |
1 |
4 |
24562 |
1 |
5 |
34764 |
65 |
请注意,"Id_O" 列是 Orders 表中的的主键,同时,"Orders" 表中的 "Id_P" 列用于引用 "Persons" 表中的人,而无需使用他们的确切姓名。
请留意,"Id_P" 列把上面的两个表联系了起来。
引用两个表
我们可以通过引用两个表的方式,从两个表中获取数据:
谁订购了产品,并且他们订购了什么产品?
SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo
FROM Persons, Orders
WHERE Persons.Id_P = Orders.Id_P
结果集:
LastName |
FirstName |
OrderNo |
Adams |
John |
22456 |
Adams |
John |
24562 |
Carter |
Thomas |
77895 |
Carter |
Thomas |
44678 |
SQL JOIN - 使用 Join
除了上面的方法,我们也可以使用关键词 JOIN 来从两个表中获取数据。
如果我们希望列出所有人的定购,可以使用下面的 SELECT 语句:
SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo
FROM Persons
INNER JOIN Orders
ON Persons.Id_P = Orders.Id_P
ORDER BY Persons.LastName
结果集:
LastName |
FirstName |
OrderNo |
Adams |
John |
22456 |
Adams |
John |
24562 |
Carter |
Thomas |
77895 |
Carter |
Thomas |
44678 |
不同的 SQL JOIN
除了我们在上面的例子中使用的 INNER JOIN(内连接),我们还可以使用其他几种连接。
下面列出了您可以使用的 JOIN 类型,以及它们之间的差异。
- JOIN: 如果表中有至少一个匹配,则返回行
- LEFT JOIN: 即使右表中没有匹配,也从左表返回所有的行
- RIGHT JOIN: 即使左表中没有匹配,也从右表返回所有的行
- FULL JOIN: 只要其中一个表中存在匹配,就返回行
三、Sql几个相近的语句
joinàunion
join根据两个表之间的联系连接表,union是将结构形式相同的表(两张表的字段个数,字段顺序,字段类型都必须一样)的结果选出所有两张表中所有不同的数据。
whereàon
同作为条件关键字时作用是一样的
whereàhaving
where关键字不能用于合计函数
group byàdistinct
这个两个关键字如果在同一个等级的查询条件时,group by要先执行,所以一般选用它去重
topàlimit
top 会做排序,而limit不会
order byàtop
两个都会做排序,但是order by不会筛选数据,top会筛选出满足条件的行