SELECT 查询的基础语法
SELECT可以从一个表或多个表中进行数据查询。
一个数据表是由列(字段名)和行(数据行)组成的,要返回满足条件的数据行,就需要在SELECT后面加上想要查询的列名,可以是一列,也可以是多个列。
实例
- 王者荣耀英雄数据表,一共63个英雄,23个属性值(不包含英雄名)。
数据表中24个字段(除id)
查询列
示例
- 检索数据表中都有哪些英雄
SQL:SELECT name FROM heros
运行结果(69条记录)
对多个列进行检索,在列名之间用逗号(,)分割。
示例
- 检索有哪些英雄,他们的最大生命、最大法力、最大物攻和最大物防分别是多少
SQL:SELECT name, hp_max, mp_max, attack_max, defense_max FROM heros
运行结果(69条记录)
查询所有字段名称
SQL:SELECT * FROM heros
运行结果(69条记录)
注:生产环境时尽量避免使用SELECT *
起别名
使用SELECT查询的时候,可以给列名起别名
示例
- 在检索时,给英雄名、最大声明、最大法力、最大物攻和最大物防等取别名
SQL:SELECT name AS n, hp_max AS hm, mp_max AS mm, attack_max AS am, defense_max AS dm FROM heros
查询常数
SELECT查询还可以对常数进行查询
示例
- 对heros数据表中英雄名进行拆线呢,同时增加一列字段platform,这个字段固定值为王者荣耀
SQL:SELECT '王者荣耀' as platform, name FROM heros
运行结果(69条记录)
相当虚构了一个platform字段,并且把它设置为固定值“王者荣耀”
注:如果常数是个字符串,需要使用单引号。单引号说明引号中的字符串是个常数,否则SQL会把王者荣耀当成列名进行查询。
去除重复行
使用关键字DISTINCT去重
示例
- 查询heros表中攻击范围的取值有哪些
SQL:SELECT DISTINCT attack_range FROM heros
运行结果(2条)
带上英雄的名称
SQL:SELECT DISTINCT attack_range, name FROM heros
运行结果(69条记录)
注意:
1、DISTINCT需要放到所有列名的前面,否则会报错
2、DISTINCT其实是对后面所有列名的组合进行去重。
如果排序检索数据
检索数据,需要按照某种顺序进行结果的返回,就需要使用ORDER BY子句
ORDER BY知识点:
1、排序的列名:ORDER BY后面有一个或多个列名,如果是多个列名进行排序,会按照后面第一个列先进行排序,当第一列的值相同的时候,在按照第二列进行排序,一次类推。
2、排序的顺序:ORDER BY后面可以注明排序顺序,ASC代表递增排序,DESC代表递减排序。默认ASC递增排序。
3、非选择列排序:ORDER BY可以使用非选择列进行排序,即使在SELECT后面没有这个列名,也可以放到ORDER BY后面进行排序
4、ORDER BY的位置:ORDER BY通常位于SELECT语句的最后一条子句,否则会报错
示例
- 查询英雄名称及最大生命值,按照最大生命值从高到低的方式进行排序
SQL:SELECT name, hp_max FROM heros ORDER BY hp_max DESC
运行结果(69条记录)
显示英雄名称及最大生命值,按照第一排序最大法力从低到高,当最大法力值相等时按照第二排序进行,即最大生命值从高到低的方式进行排序
SQL:SELECT name, hp_max FROM heros ORDER BY mp_max, hp_max DESC
运行结果(69条记录)
约束返回结果的数量
约束返回结果的数量,使用LIMIT关键字
示例
- 返回英雄名称及最大生命值,按照最大生命值从高到低排序,返回5条记录。
SQL:SELECT name, hp_max FROM heros ORDER BY hp_max DESC LIMIT 5
运行结果(5条记录)
注:约束返回结果的数量,在不同的DBMS中使用的关键字不同。MySQL、postgreSQL、SQLite中使用LIMIT关键字。
SELECT 的执行顺序
SELECT查询时的两个顺序
1、关键字的顺序时不能颠倒的
SELECT ... FROM ... WHERE ... GROUP BY ... HAVING ... ORDER BY ...
2、SELECT语句的执行顺序(MySQL和Oracle中,顺序基本相同)
FROM > WHERE > GROUP BY > HAVING > SELECT的字段 > DISTINCT > ORDER BY > LIMIT
示例
SELECT DISTINCT player_id, player_name, count(*) as num #顺序5FROM player JOIN team ON player.team_id = team.team_id #顺序1WHERE height > 1.80 #顺序2GROUP BY player.team_id #顺序3HAVING num > 2 #顺序4ORDER BY num DESC #顺序6LIMIT 2 #顺序7
SELECT语句执行这些步骤时,都会产生一个虚拟表,然后将这个虚拟表传入下一个步骤作为输出。这些步骤隐含在SQL的执行过程中。
SQL的执行原理
1、首先先通过CROSS JOIN求笛卡尔积,相当于得到虚拟表vt1-1
2、通过ON进行筛选,在虚拟表vt1-1的基础上进行排序,得到虚拟表vt1-2
3、添加外部行。如果使用的是左连接、右连接或者全连接,就会设计到外部行,也就是在虚拟表vt1-2的基础上增加外部行,得到虚拟表vt1-3
如果操作的是两张以上的表,会重复上面的步骤,直到所有表都被处理完为止。
当拿到了数据表的原始数据,也就是最终的虚拟表vt1,就可以在此基础上在进行WHERE阶段。
然后进入第三步和第四步,也就是GROUP和HAVING阶段。实际上是在虚拟表vt2的基础上进行分组和分组过滤,得到中间的虚拟表vt3和vt4.
当完成条件筛选部分之后,就可以筛选表中提取的字段,进入到SELECT和DISTINCT阶段。
SELECT阶段会提取想要的字段,然后再DISTINCT阶段过滤掉重复的行,分别得到中间的虚拟表vt5-1和vt5-2.
之后就可以按照指定的字段进行排序,就是ORDER BY阶段,得到虚拟表vt6
最后再vt6的基础上,取出指定行的记录,也就是LIMIT阶段,得到最终的结果,对应的就是虚拟表vt7。
总结