DQL(数据查询语言)


数据查询语言

这章例子:

select 字段列表 from 表名列表
[ where 条件列表 ]
[ group by 分组字段列表 ]
[ having 分组后条件列表 ]
[ order by 排序字段列表 ]
[ limit 分页参数 ];
  • 基本查询(不带任何条件)
  • 条件查询(where)
  • 聚合函数(count、max、min、avg、sum)
  • 分组查询(group by)
  • 排序查询(order by)
  • 分页查询(limit)

基础查询

查询多个字段

select 字段1, 字段2, 字段3 ... from 表名 ;SELECT * FROM 表名 ;

* 号代表查询所有字段,在实际开发中尽量少用(不直观、影响效率)。

字段设置别名

select 字段1 [ 别名1 ] , 字段2 [ 别名2 ] ... from 表名;

去除重复记录

select distinct 字段列表 from 表名;

条件查询

支持:

  • 比较运算符
  • 逻辑运算符
  • _ 占位符,一条下划线占一个位
  • % 通配符,相当于正则

例如:

  • 查询年龄在15岁(包含) 到 20岁(包含)之间的员工信息
select * from emp where age >= 15 && age <= 20;
  • 查询姓名为两个字的员工信息
select * from emp where name like '__';
  • 查询身份证号最后一位是 X 的员工信息
select * from emp where idcard like '%X';

聚合函数

将一列数据作为一个整体,进行纵向计算

常见的聚合函数

函数功能
count统计数量
max最大值
min最小值
avg平均值
sum求和
select 聚合函数(字段列表) from 表名 ;

注意:NULL 值是不参与所有聚合函数运算的

例如:

  • 统计该企业员工数量
select count(idcard) from emp; -- 统计的是idcard字段不为null的记录数
  • 统计西安地区员工的年龄之和
select sum(age) from emp where workaddress = '西安';

分组查询

SELECT 字段列表 FROM 表名 [ WHERE 条件 ] GROUP BY 分组字段名 [ HAVING 分组后过滤条件 ];

where 与 having 区别

  • 执行时机不同:where是分组之前进行过滤,不满足where条件,不参与分组;而having是分组之后对结果进行过滤
  • 判断条件不同:where不能对聚合函数进行判断,而having可以

注意:

  • 分组之后,查询的字段一般为聚合函数和分组字段,查询其他字段无任何意义
  • **执行顺序: where > 聚合函数 > having **
  • 支持多字段分组, 具体语法为: group by columnA,columnB

例子:

  • 根据性别分组 , 统计男性员工 和 女性员工的数量
select gender, count(*) from emp group by gender;
  • 查询年龄小于45的员工 , 并根据工作地址分组 , 获取员工数量大于等于3的工作地址
select workaddress, count(*) address_count from emp where age < 45 group by workaddress having address_count >= 3;
  • 统计各个工作地址上班的男性 及 女性员工的数量
select workaddress, gender, count(*) '数量' from emp group by gender , workaddress;
+-------------+--------+------+
| workaddress | gender | 数量 |
+-------------+--------+------+
| 北京        | 女     |    4 |
| 北京        | 男     |    4 |
| 上海        | 男     |    2 |
| 上海        | 女     |    1 |
| 天津        | 女     |    1 |
| 江苏        | 男     |    2 |
| 西安        | 女     |    1 |
| 西安        | 男     |    1 |
+-------------+--------+------+
8 rows in set (0.07 sec)


排序查询

select 字段列表 from 表名 order by 字段11 序方式1 , 字段2 排序方式2 ;

排序方式:

  • asc:升序(默认)
  • desc:降序

例如:

  • 根据年龄对公司的员工进行降序排序
select * from emp order by age desc;
  • 根据年龄对公司的员工进行升序排序 , 年龄相同 , 再按照入职时间进行降序排序
select * from emp order by age asc, entrydate desc;

分页查询

分页操作在业务系统开发时,也是非常常见的一个功能,我们在网站中看到的各种各样的分页条,后台都需要借助于数据库的分页操作

select 字段列表 from 表名 limit 起始索引, 查询记录数 ;
  • 起始索引从0开始,起始索引 = (查询页码 - 1)* 每页显示记录数。
  • 分页查询是数据库的方言,不同的数据库有不同的实现,MySQL 中是 LIMIT。
  • 如果查询的是第一页数据,起始索引可以省略,直接简写为 limit 10

例子:

  • 查询第1页员工数据, 每页展示10条记录
select * from emp limit 0,10;
select * from emp limit 10;
  • 查询第2页员工数据, 每页展示10条记录 —> ( 2 − 1 ) ∗ 10 = 10 (2 - 1)*10=10 (21)10=10
select * from emp limit 10,10;

执行顺序

image.png

经典案例

摘至黑马 MySQL 文档

(1)查询年龄为20,21,22,23岁的员工信息

select * from emp where gender = '女' and age in(20,21,22,23);

(2)查询性别为 男 ,并且年龄在 20-40 岁(含)以内的姓名为三个字的员工

select * from emp where gender = '男' and ( age between 20 and 40 ) and name like '___';

(3)统计员工表中, 年龄小于60岁的 , 男性员工和女性员工的人数

select gender, count(*) from emp where age < 60 group by gender;

(4)查询所有年龄小于等于35岁员工的姓名和年龄,并对查询结果按年龄升序排序,如果年龄相同按入职时间降序排序

select name , age from emp where age <= 35 order by age asc, entrydate desc;

(5)查询性别为男,且年龄在20-40 岁(含)以内的前5个员工信息,对查询的结果按年龄升序排序,年龄相同按入职时间升序排序

select * from emp where gender = '男' and age between 20 and 40 order by age asc, entrydate asc limit 5 ;

多表查询

多表关系

一对一

  • 例子:用户 与 用户详情的关系
  • 关系:一对一关系,多用于单表拆分,将一张表的基础字段放在一张表中,其他详情字段放在另一张表中,以提升操作效率
  • 实现:在任意一方加入外键,关联另外一方的主键,并且设置外键为唯一的(UNIQUE)

一对多

  • 例子:部门 和 员工的关系
  • 关系:一个部门对应多个员工,一个员工对应一个部门
  • 实现:在**⌈** 多 的一方建立外键,指向 一 **⌋**的一方的主键

image.png

多对多

  • 例子:学生 与 课程的关系
  • 关系:一个学生可以选修多门课程,一门课程也可以供多个学生选择
  • 实现:建立第三张中间表,中间表至少包含两个外键,分别关联两方主键

image.png

连接

image.png

在查询时数据的冗杂会导致效率低下,必须要筛掉笛卡尔积中的大部分情况

建立连接查询可以有效去除冗杂的笛卡尔积

  • 内连接:相当于查询A、B交集部分数据
  • 左外连接:查询左表所有数据,以及两张表交集部分数据
  • 右外连接:查询右表所有数据,以及两张表交集部分数据
  • 自连接:当前表与自身的连接查询,自连接必须使用表别名

内连接

查询两表交集部分数据

隐式内连接
select 字段列表 from1,2 where 条件... ;
显式内连接
select 字段列表 from1 [ INNER ] join2 on 连接条件 ... ;

例如:

查询每一个员工的姓名 , 及关联的部门的名称

  • 隐式内连接
select e.name,d.name from emp e , dept d where e.dept_id = d.id;
  • 显式内连接
select e.name, d.name from emp e join dept d on e.dept_id = d.id;

左外连接

查询左表(表1)所有数据,以及两张表交集部分数据

select 字段列表 from1 left [ outer ] join2 on 条件 ... ;

右外连接


查询右表所有数据,以及两张表交集部分数据

select 字段列表 from1 right [ outer ] join2 on 条件 ... ;

自连接

自己连接自己

select 字段列表 from 表A 别名A join 表A 别名B on 条件 ... ;

例如:
emp 表结构

+----+--------+-----+--------------+--------+------------+-----------+---------+
| id | name   | age | job          | salary | entrydate  | managerid | dept_id |
+----+--------+-----+--------------+--------+------------+-----------+---------+
|  1 | 金庸   |  66 | 总裁         |  20000 | 2000-01-01 | NULL      |       5 |
|  2 | 张无忌 |  20 | 项目经理      |  12500 | 2005-12-05 |         1 |       1 |
|  3 | 杨逍   |  33 | 开发          |   8400 | 2000-11-03 |         2 |       1 |
|  4 | 韦一笑 |  48 | 开发          |  11000 | 2002-02-05 |         2 |       1 |
|  5 | 常遇春 |  43 | 开发          |  10500 | 2004-09-07 |         3 |       1 |
|  6 | 小昭   |  19 | 程序员鼓励师  |   6600 | 2004-10-12 |         2 |       1 |
+----+--------+-----+--------------+--------+------------+-----------+---------+

查询所有员工 emp 及其领导的名字 emp , 如果员工没有领导, 也需要查询出来

select a.name '员工', b.name '领导' from emp a left join emp b on a.managerid = b.id;

结果:

+--------+--------+
| 员工   | 领导   |
+--------+--------+
| 金庸   | NULL   |
| 张无忌 | 金庸   |
| 杨逍   | 张无忌 |
| 韦一笑 | 张无忌 |
| 常遇春 | 杨逍   |
| 小昭   | 张无忌 |
+--------+--------+
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值