06 基础查询-单表01
数据库既然是存储数据的,那么做数据的检索就是必不可少了。查询数据操作是数据库中使用频率最高的操作,学习方案是:
- 单表查询
- 子查询
- 连接查询
- 组合查询
SQL执行顺序
查询SQL在解析的时候的先后顺序如下:
- from
- join
- on
- where
- group by(开始使用select中的别名,后面的语句中都可以使用)
- avg,sum.... (聚合函数)
- having
- select
- distinct
- order by
- limit
以 Emp 雇员表为操作表,进行基础的数据检索。
检索所有列或某个列
在基础的数据操作中,我们使用过 select 语句检索数据。select 语句的用途是从一个或多个表中检索 信息。
1. 检索所有列,非星号
select empid, ename, age, phone, email from emp;
为了使用SELECT检索表数据,必须至少给出两条信息
- 从什么地方选择
- 想选择什么
查询顺序
以 下面的 select 语句来分析
select empid, ename, age, phone, email from emp;
**执行的第一步:**先找到数据库表
from emp e;
**执行的第二步:**检索表中的列
select empid, ename, age, phone, email /* 这是第二个步骤 */
表是可以起别名的,如果有别名的话,我们检索数据就可以以别名为开始
select e.empid, e.ename, e.age, e.phone, e.email from emp e;
2. 检索单个列
select ename as 雇员姓名 from emp;
和检索所有列一样,只需列出需要的列名即可。
列名也是可以起别名的。通过 as
关键字后面跟上别名即可。也可以省却 as
关键字,在列名后面通过空格,跟上别名。
给列起别名后,操作列的时候都需使用别名。
limit 分页(限制结果数量)
select 语句可以返回所有匹配的数据。但是如果数据量比较大,比如100W条,可是我们仅需要前5 条数据,这时候我们就需要使用分页来完成数据的检索。
示例:返回 emp 表不多于 5 行的数据(因为有可能数据没有5行)
select empid, ename, age, phone, email from emp limit 5;
示例:从表 行5 开始检索 3 行数据
select empid, ename, age, phone, email from emp limit 5 , 3;
带一个值的LIMIT总是从第一行开始,给出的数为返回的行数。带两个值的LIMIT可以指定从行号为第一个值的位置开始
行0 :检索出来的第一行为行0而不是行1。因此,LIMIT 1, 1 将检索出第二行而不是第一行。
查询顺序
- from emp
- select 列
- limit
去重复distinct
distinct关键字的主要作用就是对数据库表中一个或者多个字段重复的数据进行过滤,只返回其中的一条数据给用户,distinct只可以在select中使用 。
语法:
select distinct expression[,expression...] from tables ;
在使用distinct的过程中主要注意一下几点:
- 在对字段进行去重的时候,要保证distinct在所有字段的最前面
- 如果distinct关键字后面有多个字段时,则会对多个字段进行组合去重,只有多个字段组合起来的值是相等的才会被去重
假设有表数据如下:
对单个字段进行去重sql:
select distinct age from user;
查询结果
age
10
20
30
对多个字段进行去重sql:
select distinct name,age from user;
查询结果
name age
One 10
Zero 20
Two 20
Four 30
One 30
对多个字段进行去重并求count的sql:
select count(distinct name,age) as total from user;
查询结果
total
5
对 select * 进行去重
-- 由于 * 代表所有字段,所以该sql和 select distinct id,name,age,sign from user 语义相同,但是开发中应避免使用星号
select distinct * from user;
查询结果:
id name age sign
1 One 10 梦想要有的,万一实现了呢
2 Zero 20 http://www.chaoshizhushou.com
3 Two 20 OneZeroTwoFour
4 Four 30 加油
5 One 30 学习才是硬道理
6 Four 30 一日三省吾身
使用 where 过滤数据
数据库表一般包含大量的数据,很少需要检索表中所有行。通常只会根据特定操作或报告的需要提取表数据的子集。只检索所需数据需要指定搜索条件(search criteria),搜索条件也称为过滤条件(filter condition)
在SELECT语句中,数据根据WHERE子句中指定的搜索条件进行过滤。
MySQL在执行匹配时默认不区分大小写
示例
WHERE子句在表名(FROM子句)之后给出
select ename, phone from emp where empid = 101;
查询顺序
- from emp
- where 条件约束
- select 列名
where 后面的语句都是 布尔表达式,即符合条件的数据留下,不符合条件的数据过滤掉
运算操作符
符号 | 描述 | 备注 |
= | 等于 | |
<>, != | 不等于 | |
> | 大于 | |
< | 小于 | |
<= | 小于等于 | |
>= | 大于等于 | |
BETWEEN | 在两值之间 | >= 最小值 && <=最大值 |
NOT BETWEEN | 不在两值之间 | |
IN | 在集合中 | |
NOT IN | 不在集合中 | |
<=> | 严格比较两个NULL值是否相等 | 两个操作码均为NULL时,其所得值为1;而当一个操作码为NULL时,其所得值为0 |
LIKE | 模糊匹配 | |
REGEXP 或 RLIKE | 正则式匹配 | |
IS NULL | 为空 | |
IS NOT NULL | 不为空 |
检查单个值
select ename, phone from emp where empid = 101;
不匹配检查
select ename from emp where age <> 24;
AND 操作符
当查询数据的时候我们需要对不止一个列进行过滤,可使用AND操作符给WHERE子句附加条件。
select ename from emp where age > 20 and phone = 13412345678
上述例子中使用了只包含一个关键字AND的语句,把两个过滤条件组合在一起。还可以添加多个过滤条件,每添加一条就要使用一个AND。
OR 操作符
OR操作符与AND操作符不同,它用来表示检索匹配任一给定条件的行。
select ename from emp where age > 20 or phone = 13512345678
这条 SQL 查询只是把 and 关键字换成了 or 关键字,但是结果却完全不一样。
范围检查
为了检查某个范围的值,可使用操作符:
- BETWEEN
- >
- >=
- <
- <=
select ename from emp where age between 20 and 23;
在使用 between 时,必须指定两个值——所需范围的低端值和高端值。这两个值必须用AND关键字分隔。between 匹配范围中所有的值,包括指定的开始值和结束值
空值检查
在创建表时,表设计人员可以指定其中的列是否可以不包含值。在一个列不包含值时,称其为包含空值NULL。NULL 无值(no value) ,它与字段包含0、空字符串或仅仅包含空格不同。
-- 空值检查
select ename from emp where ename is null;
-- 非空值检查
select ename from emp where ename is not null;
优先级(小括号)
WHERE可包含任意数目的AND和OR操作符。允许两者结合以进行复杂和高级的过滤。但有时候我们发出的SQL语句却被错误的理解了。
示例:通过查询雇员编号 10004和 10005的雇员,看2人谁的手机号码是 15488899081
select empid , ename , phone from emp where empid = 10005 or empid = 10004 and phone = 15488899081
结果
结果是2个人的信息都被查询出来了,这个不符合我们的要求。
解决方法:使用小括号提升优先级
select empid , ename , phone from emp where (empid = 10005 or empid = 10004) and phone = 15488899081
in 操作符
圆括号在WHERE子句中还有另外一种用法。IN操作符用来指定条件范围,范围中的每个条件都可以进行匹配。IN取合法值的由逗号分隔的清单,全都括在圆括号中。
示例:检索 雇员编号是 10001,10004 的两个雇员信息
select empid ,ename ,sex , phone , email from emp where empid in (10001 , 10004)
in 操作符优点
- 在使用长的合法选项清单时,IN操作符的语法更清楚且更直观。
- 在使用IN时,计算的次序更容易管理(因为使用的操作符更少) 。
- IN操作符一般比OR操作符清单执行更快。
- IN的最大优点是可以包含其他SELECT语句,使得能够更动态地建立WHERE子句。
指定要匹配值的清单的关键字
not 操作符
WHERE子句中的NOT操作符有且只有一个功能,那就是否定它之后所跟的任何条件。
示例:匹配除了雇员编号 10001 , 10004 的其他雇员信息
select empid ,ename ,sex , phone , email from emp where empid not in (10001 , 10004)
在更复杂的子句中,NOT是非常有用的。例如,在与IN操作符联合使用时,NOT使找出与条件列表不匹配的行非常简单
MySQL支持使用NOT对 IN、BETWEEN 和 EXISTS 子句取反,这与多数其他DBMS允许使用NOT对各种条件 取反有很大的差别
like 模糊查询(通过通配符过滤)
当搜索的内容变的不确定的时候,我们可以使用 like 关键字进行模糊查询。这需要使用通配符来完成操作。
1. 百分号 (%) 通配符
最常使用的通配符是百分号(%) 。在搜索串中,%表示任何字符出现的位置。
示例:搜索手机号 134 开头的雇员信息
select empid , ename , phone from emp where phone like '134%'
示例:搜索电子邮箱是 863.com 的雇员
select empid , ename , phone,email from emp where email like '%@863.com'
示例:搜索手机号中间有 1234 的雇员
select empid , ename , phone,email from emp where phone like '%1234%'
示例:搜索手机号开头为134,结尾是8的雇员
select empid , ename , phone,email from emp where phone like '134%8'
虽然似乎%通配符可以匹配任何东西,但有一个例外,即NULL
2. 下划线 (_)通配符
下划线的用途与%一样,但下划线只匹配单个字符而不是多个字符。
示例:通过2个下划线匹配姓名
select empid , ename , phone,email from emp where ename like 'J__k'
使用通配符的注意事项
MySQL的通配符很有用。但这种功能是有代价的:通配符搜索的处理一般要比前面演示的搜索所方式更花时间。
- 不要过度使用通配符。如果其他操作符能达到相同的目的,应该使用其他操作符。
- 在确实需要使用通配符时,除非绝对有必要,否则不要把它们用在搜索模式的开始处。把通配符置于搜索模式的开始处,搜索起来是最慢的。
- 仔细注意通配符的位置。如果放错地方,可能不会返回想要的数据。