执行顺序
MySQL中执行顺序:from—where–group by—having—select—order by
粗浅的理解的话,
SELECT的语法顺序就是其执行顺序
SELECT
FROM
WHERE (先过滤单表/视图/结果集,再JOIN)
GROUP BY
HAVING (WHERE过滤的是行,HAVING过滤的是组,所以在GROUP之后)
ORDER BY
- 使用count(col_name): 当某列出现null值的时候,count(*)仍然会计算,但是count(col_name)不会。
- 数据分组(group by): select [col_a], 聚合函数(min, max, avg, count)[聚合条件] from [table_name] where [过滤条件] group by [col_a];
- group by 子句和where子语结合在一起使用。当结合在一起时,where在前,group by 在后。 即先对select xx from xx的记录集合用where进行筛选,然后再使用group by 对筛选后的结果进行分组。
- 使用having字句对分组后的结果进行筛选,语法和where差不多: having [条件表达式]
需要注意having和where的用法区别:
- having只能用在group by之后,对分组后的结果进行筛选(即使用having的前提条件是分组)。
- where肯定在group by 之前,即也在having之前。
- where后的条件表达式里不允许使用聚合函数(count(),sum(),avg(),max(),min()),而having可以。
- 当一个查询语句同时出现了where,group by,having,order by的时候,执行顺序和编写顺序是:
- 1.执行where xx对全表数据做筛选,返回第1个结果集。
- 2.针对第1个结果集使用group by分组,返回第2个结果集。
- 3.针对第2个结果集中的每1组数据执行select xx,有几组就执行几次,返回第3个结果集。
- 4.针对第3个结集执行having xx进行筛选,返回第4个结果集。
- 5.针对第4个结果集排序。
例子
完成一个复杂的查询语句,需求如下:
按由高到低的顺序显示个人平均分在70分以上的学生姓名和平均分,为了尽可能地提高平均分,在计算平均分前不包括分数在60分以下的成绩,并且也不计算贱人(jr)的成绩。 分析:
1.要求显示学生姓名和平均分
因此确定第1步select s_name,avg(score) from student
2.计算平均分前不包括分数在60分以下的成绩,并且也不计算贱人(jr)的成绩
因此确定第2步 where score>=60 and s_name!=’jr’
3.显示个人平均分相同名字的学生(同一个学生)考了多门科目 因此按姓名分组确定第3步 group by s_name
4.显示个人平均分在70分以上因此确定第4步 having avg(s_score)>=70
5.按由高到低的顺序因此确定第5步 order by avg(s_score) desc
SELECT name, avg(score)
FROM student
WHERE score >= 60 and name != 'jr'
GROUP BY name
HAVING avg(scor) >= 70
ORDER BY avg(score) DESC;
JOIN
- JOIN: 如果表中有至少一个匹配,则返回行
- LEFT JOIN: 即使右表中没有匹配,也从左表返回所有的行
- RIGHT JOIN: 即使左表中没有匹配,也从右表返回所有的行
- FULL JOIN: 只要其中一个表中存在匹配,就返回行
- INNER JOIN 与 JOIN 相同
示例
表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 |
表Orders
Id_O | OrderNo | Id_P |
---|---|---|
1 | 77895 | 3 |
2 | 44678 | 3 |
3 | 22456 | 1 |
4 | 24562 | 1 |
5 | 34764 | 65 |
INNER 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 |
LEFTJOIN示例
SELECT语句
SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo
FROM Persons
LEFT 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 |
Bush | George |
RIGHT JOIN示例
SELECT语句
SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo
FROM Persons
RIGHT 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 |
34764 |
FULL JOIN
SELECT语句
SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo
FROM Persons
RIGHT 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 |
Bush | George | |
34764 |
原文链接:https://blog.csdn.net/superhosts/article/details/39298529