MySQL(零基础)详解之DQL
目录
一、DQL
1.1、语法结构
1.2、着重号
1.3、SQL简单使用
二、别名查询
2.1、给字段名取别名
2.2、给表取别名
三、去重查询(distinct)
四、单表查询
4.1、算术运算符
4.2、比较运算符
4.3、逻辑运算符
4.4、范围和集合
4.5、模糊查询
4.6、统计查询
4.7、分页查询(limit)
4.8、分组查询
4.9、排序查询
五、多表查询
5.1、笛卡尔积
5.2、关联查询
5.3、内连接
5.4、外连接
5.4.1、左外连接
5.4.2、右外连接
5.4.3、全外连接(union)
5.5、自连接
六、子查询
6.1、where 型子查询
6.2、from 型子查询
6.3、exists 型子查询
6.4、复制表子查询
6.4.1、复制表结构
6.4.2、复制表结构和数据
6.4.3、复制表结构+数据
6.4.4、跨数据库复制
6.4.5、复制表中部分字段和数据
6.4.6、在创建表的同时定义表的字段
一、DQL
1.1、语法结构
select 字段列表
from 表名或视图
[where 条件]
[group by 字段列表
[having 分组条件]]
[order by 字段 [asc | desc]]
[limit m, n]
语法说明:
(1)使用 select 关键字来做查询;
(2)字段列表是使用英文逗号来进行分割 ;
(3)from关键字后跟表的,可以是多个表名称或视图名称;
(4)group by:用于分组查询;
(5)having:用于结分组查询时进行过滤——条件的筛选;
(6)order by:用于数据显示时的排序;
(7)asc:表示长序,它是默认值;
(8)desc:表示降序;
(9)limit:用于分页显示,它有两个参数,第一个参数是起始值,第二个参数是显示的数量。
1.2、着重号
有些字段或表名可以使用了数据库的关键字或保留,这时我们就可以使用着重号(也叫反引号``)来进行着重标明
示例:
select `name` from t_stu;
1.3、SQL简单使用
示例一:查询员工表中所有行所有列
select * from t_employee;
![](/assets/blank.gif)
注意:在实际开发中,不建议在SQL中使用 *号
示例二:查询部分字段
select eid,ename,gender from t_employee;
示例三:查询员工表中性别为男的数据
select eid,ename,gender from t_employee where gender='男';
二、别名查询
2.1、给字段名取别名
select ename as '员工姓名',tel '手机号' from t_employee;
2.2、给表取别名
select eid, ename as name, gender, tel from t_employee as e;
select t_employee.eid, ename as name, gender, tel from t_employee as e;
select e.eid, ename as name, gender, tel from t_employee as e;
三、去重查询(distinct)
select gender from t_employee;
select distinct gender from t_employee;
这个关键字好用,但是要慎用。因为它会做全表扫描,然后再把数据进行去重后再展示出来。比 较耗性能。
注意:这个关键字尽量少用或不用。
四、单表查询
4.1、算术运算符
select eid,ename,gender,tel from t_employee where eid%2=1;
示例二:筛选出eid除以2后等于1的数据
select eid,ename,gender,tel from t_employee where eid div 2=1;
4.2、比较运算符
select * from t_salary where basic_salary != 10000;
示例二: 查询 commission_pct 等于 null 数据
select * from t_salary where commission_pct = null;
select * from t_salary where commission_pct is null;
4.3、逻辑运算符
select eid,ename,gender,birthday from t_employee where gender='男' and birthday < '1990-01-02';
上面的 SQL 语句也可以写成如下形式:
select eid,ename,gender,birthday from t_employee where gender='男' && birthday < '1990-01-02';
示例二:查询职位编号 job_id 是 1 或 2 的员工
select job_id, job_name, description from t_job where job_id=1 or job_id=2;
上面的SQL语句也可以写成如下形式:
select job_id, job_name, description from t_job where job_id=1 || job_id=2;
4.4、范围和集合
select eid, basic_salary from t_salary where basic_salary between 9000 and 12000;
注意:between...and... 查询时,条件是一个闭区间查询。并且后一个值要大于前一个值。
上面的SQL语句和一面这条SQL语句执行结果是一样的。
select eid,basic_salary from t_salary where basic_salary>=9000 and basic_salary<=12000;
示例二:查询 eid 的值为 1、3、5的基本薪资。
select eid,basic_salary from t_salary where eid=1 or eid=3 or eid=5;
上面的SQL语句是可以正确的查询出我们想要的结果。但是这种查询效率很低,我们不推荐SQL 使用 or 查询,因为它会做全表扫描。
select eid,basic_salary from t_salary where eid in (1,3,5);
4.5、模糊查询
select eid,ename,gender,tel from t_employee where ename like '%孙%';
select eid,ename,gender,tel from t_employee where ename like '孙%';
select eid,ename,gender,tel from t_employee where ename like '孙_';
上面的SQL语句表示姓名是以孙开头,并且名字中只有两个字。
4.6、统计查询
select avg(basic_salary) as '平均工资' from t_salary;
select max(basic_salary) as '最高工资' from t_salary;
示例三:获取工资表中最低的工资
select min(basic_salary) as '最低工资' from t_salary;
示例四:获取所有员工的工资总和
select sum(basic_salary) as '工资总和' from t_salary;
示例五:获取员工总数
select count(*) as '员工总数' from t_salary;
4.7、分页查询(limit)
limit offset,pagecount;
(1)offset:它是分页的起始偏移值,它需要计算;
(2)pagecount:显示的记录数
示例一:分页显示员工信息,每页显示 2 名员工。
select eid,ename,gender,tel,birthday from t_employee limit 0, 2;
select eid,ename,gender,tel,birthday from t_employee limit 2, 2;
第三页数据:
select eid,ename,gender,tel,birthday from t_employee limit 4, 2;
从上面的三条SQL语句可以发现,唯一变化的是 offset 这个参数,而这个参数的计算是根据页码和每页显示的记录数来计算而得。它的计算公式为:
4.8、分组查询
示例一:根据员工的职位来分组查询员工信息。
select eid,ename,gender,job_id from t_employee group by job_id;
[42000][1055] Expression #1 of SELECT list is not in GROUP BY clause and
contains nonaggregated column 'mydb.t_employee.eid' which is not
functionally dependent on columns in GROUP BY clause; this is incompatible
with sql_mode=only_full_group_by
select eid,ename,gender,job_id from t_employee group by eid,ename,gender,job_id;
![](/assets/blank.gif)
select job_id from t_employee group by job_id;
这次的结果确实是按员工的职位来进行分组,但是我们看不到每职位的员工有多少个。
从上面分析过程可以发现:我们的分组字段是可以写在 select 列表中的,还有统计查询的 一些函数也是可以写在分组查询中的 select 列表中的,其它的字段不能写在 select 列表 中。
select dept_id, count(*) from t_employee group by dept_id;
示例三:根据部门编号统计员工人数,要求统计的部门编号大于1
select dept_id, count(*) from t_employee group by dept_id having dept_id > 1;
![](/assets/blank.gif)
select dept_id, count(*)from t_employeewhere gender = '男'group by dept_idhaving dept_id in (1,2);
从 SQL 优化角度,我们最好是定义 where 条件来过滤大量的数据后,再使用 having 来进行过滤,这样的话性能就会高很多。
4.9、排序查询
select eid,ename,gender,tel,birthday from t_employee;
select eid,ename,gender,tel,birthday
from t_employee
order by eid desc ;
题目的要求是按员工的编号进行升序显示,因此在 SQL 就应该使用 order by 语句。
select eid,ename,gender,tel,birthday from t_employee
order by eid asc;
从上面两条 SQL 语句执行的结果可以发现,结果是一样的,也就是说,我们在查询时,默认就是按照主键的升序进行显示的。
select eid,ename,gender,tel,birthday
from t_employee
order by eid desc ;
示例二:按员工的基本工资的高低来进行显示
select eid, basic_salary
from t_salary
order by basic_salary desc;
对于排序的字段也是可以有多个的,当有多个时,会优先对第一个进行排序,只有当第一个的值相同时,才会对第二个值进行排序,依次类推。
示例三:按员工的职位高低进行排序,如果职位相同再按员工的编号升序进行排序。
select eid,ename,gender,job_id
from t_employee
order by job_id
desc,eid asc;
五、多表查询
5.1、笛卡尔积
select ename,dname from t_employee,t_department;
从上面的查询结果可以发现,我们在做关联查询时, 要尽量避免出现笛卡尔积的情况出现。
5.2、关联查询
(1)where:适用于所有的关联查询。
(2)on:只能和 join一起使用,只能写在关联条件中,但是它可以和 where 一起使用。
(3)using:只能和 join 一起使用,并且要求两个关联的字段在关联表中名称一致。
示例一:把关联条件写在 where 语句中
select ename,dname
from t_employee,t_department
where dept_id=did;
示例二:把关联条件写在 on 语句中
select ename,dname
from t_employee join t_department on dept_id=did;
两条查询的结果一样。
示例三:查询员工姓名和它的基本工资信息
select ename,basic_salary
from t_employee as e,t_salary as s
where e.eid=s.eid;
select ename,basic_salary
from t_employee e join t_salary ts on e.eid = ts.eid;
select ename,basic_salary
from t_employee join t_salary using (eid);
注意:要想使用 using,那么必须要关联查询相关表中被关联的条件字段名称必须相同。
示例四:查询员工姓名、基本工资和所在部门名称
(1)员工姓名:在 t_employee 表中
(2)基本工资:在 t_salary 表中
(3)部门名称:在 t_deparment 表中
select ename,basic_salary,dname
from t_employee e join t_salary using(eid) join t_department td on td.did = e.dept_id;
5.3、内连接
select [columns]
from 表1,表2,...
where [condition];
select [columns] from 表1 inner join 表2 on [condition] where [其它条件]; select [columns] from 表1 cross join 表2 on [condition] where [其它条件];select [columns] from 表1 join 表2 on [condition] where [其它条件];
执行关联查询后的结果为如上图所示的红色区域内的数据。也就是两张表中共同的部分。
select ename,dname
from t_employee e inner join t_department td on td.did = e.dept_id;
select ename,dname
from t_employee e join t_department td on td.did = e.dept_id;
select ename,dname
from t_employee e cross join t_department td on td.did = e.dept_id;
5.4、外连接
5.4.1、左外连接
![](/assets/blank.gif)
insert into t_department(dname, description) values('财务部', '发工资部门');
![](/assets/blank.gif)
示例一:查询所有部门信息以及部门员工信息
select did,dname,description, ename,gender,tel
from t_department td left join t_employee te on td.did=te.dept_id;
![](/assets/blank.gif)
如果以员工表为左表,那么查询的结果就不一样:
select ename,gender,tel,did,dname,description
from t_employee te left join t_department td on te.dept_id=td.did;
上面的示例是返回左表中所有行,如果左表中的行在右表中没有匹配的数据,则会以空值来填充。
![](/assets/blank.gif)
select did,dname,description,eid,ename,tel,dept_id
from t_department td left outer join t_employee te on td.did = te.dept_id
where te.dept_id is null;
示例三:查询所有员工信息,以及员工所在的部门信息
insert into t_employee(ename) values('刘备');
5.4.2、右外连接
![](/assets/blank.gif)
select eid,ename,gender,did,dname,description
from t_employee e right join t_department d on e.dept_id=d.did;
(2)查询右表在左表中没有的数据。
示例二:查询没有员工的部门信息。
select eid,ename,gender,did,dname,description
from t_employee e right join t_department d on e.dept_id=d.did
where dept_id is null;
5.4.3、全外连接(union)
select column_list
from 表1 left join 表2
on 条件
union
select column_list
from 表1 right join 表2
on 条件
![](/assets/blank.gif)
select did,dname,eid,ename,gender,tel
from t_department d left join t_employee te on d.did = te.dept_id
union
select did,dname,eid,ename,gender,tel
from t_department d right join t_employee te on d.did = te.dept_id;
(2)查询所有没有员工的部门和没有部门的员工信息
select did,dname,eid,ename,gender,tel
from t_department d left join t_employee te on d.did = te.dept_id
where te.dept_id is null
union
select did,dname,eid,ename,gender,tel
from t_department d right join t_employee te on d.did = te.dept_id
where te.dept_id is null;
5.5、自连接
update t_employee set mid=1 where eid=7;
select e1.ename, e2.ename
from t_employee e1, t_employee e2
where e1.mid=e2.eid;
上面的方式我们使用隐式的内连接来实现的自连接查询。
select e1.ename, e2.ename
from t_employee e1 join t_employee e2 on e1.mid=e2.eid;
六、子查询
(1)where 型子查询:把子查询作为 where 的条件(条件)
(2)from 型子查询:把子查询作为 from 的临时表(数据)
6.1、where 型子查询
select e.eid,ename,basic_salary
from t_employee e, t_salary s
where e.ename='孙红雷' and e.eid=s.eid;
第二步:查询工资比 12000 高的员工编号
select eid,basic_salary from t_salary
where basic_salary > 12000;
第三步:查询员工编号为 4 和 6 的员工信息
select eid,ename,gender,tel
from t_employee
where eid in (4,6);
根据上面三步的分析可以发现,我们所需要的条件都是另一个 SQL 语句的返回结果中,因此,我们可以使用子查询来实现上面三步的操作。
select eid,ename,gender,tel
from t_employee
where eid in (select eidfrom t_salarywhere basic_salary > (select basic_salaryfrom t_employee e, t_salary swhere e.ename='孙红雷' and e.eid=s.eid)
);
![](/assets/blank.gif)
select eid,ename, dept_id
from t_employee
where ename in ('孙红雷','鹿晗');
select eid,ename,gender,tel,dept_id
from t_employee
where dept_id in (1,1);
根据上面的分析,我们把第一步查询到的数据作为第二步查询所使用的条件即可。
select eid,ename,gender,tel,dept_id
from t_employee
where dept_id in (select dept_idfrom t_employeewhere ename in ('孙红雷','鹿晗')
);
执行结果一样
6.2、from 型子查询
select dept_id, avg(basic_salary)
from t_employee e, t_salary s
where e.eid=s.eid
group by dept_id;
通过上面的SQL语句,我们可以正确得到部门的平均工资。但是有一个小的问题:我们从查询的结果可以看到,平均工资的字段名称为 avg(basic_salary) 。这个名称不便于我们使用,为了便于后续使用,我们经这个字段取一个别名,例如叫 avg_salary。
select dept_id, avg(basic_salary) as avg_salary
from t_employee e, t_salary s
where e.eid=s.eid group by dept_id;
通过这样调整后,后续使用就比较方便了。
select e1.eid, dept_id,basic_salary
from t_employee e1 join t_salary s1
on e1.eid=s1.eid
and dept_id in (1, 2);
第三步:查询比部门平均工资高的员工和基本工资(需要把前面两步进行结合)
select te.eid, te.ename, basic_salary
from t_salary ts join t_employee teon ts.eid=te.eid
join (select dept_id, avg(basic_salary) as avg_salary from t_employee e, t_salary s where e.eid=s.eid group by dept_id ) as temp
on te.dept_id=temp.dept_id
where ts.basic_salary > temp.avg_salary;
6.3、exists 型子查询
select eid,ename,gender,dept_id
from t_employee
where dept_id is not null;
第二步:在第一步的基础上来实现最终的功能
select * from t_department
where exists(select * from t_employee);
(2)测试子查询中没有数据
select * from t_department
where exists(select * from t_employee where eid > 10);
根据上面的测试情况可以发现,我们子查询的结果不能为空,如果为空则外层查询就没有数据了;如果子查询不为空,则外层查询就会有数据。
select did,dname,description
from t_department
where exists( select eid,ename,gender,dept_id from t_employee where dept_id is not null
);
上面的结果中包含了没有员工的部门——财务部,这显然不符合我们的题要求,原因在于我们子查询中条件给的不对,因为没有我外部表进行关联,导致条件不符合。
select did,dname,description
from t_department td
where exists( select eid,ename,gender,dept_id from t_employee te where td.did=te.dept_id
);
此时就得到了最终的结果了。
6.4、复制表子查询
6.4.1、复制表结构
create table 表名 like 被复制的表名;
![](/assets/blank.gif)
create table t_stu_new like t_stu;
desc t_stu_new;
6.4.2、复制表结构和数据
create table 表名 as (select * from 被复制的表名);
create table t_stu_new_2 as (select * from t_stu);desc t_stu_new_2;
select * from t_stu_new_2;
6.4.3、复制表结构+数据
insert into 复制后的表名 select * from 被复制的表名;
create table t_stu_new_3 like t_stu;
再向这个表添加数据
insert into t_stu_new_3 select * from t_stu; select * from t_stu_new_3;
6.4.4、跨数据库复制
语法格式为:
create table 表名 like 被复制数据库名.被复制的表名; create table 新数据库名.表名 like 被复制数据库名.被复制的表名;
6.4.5、复制表中部分字段和数据
create table 表名 as (
select 要复制的字段列表
from 被复制的表名
where 条件
)
create table t_stu_new_4 as (
select id,name
from t_stu
where id=1
)
desc t_stu_new_4;
再查看数据
lect * from t_stu_new_4;
6.4.6、在创建表的同时定义表的字段
语法格式为:
create table 表名(字段名 类型(长度) [主键][自增][非空][默认值][注释]
) as (
select 被复制的字段 from 被复制的表名
)
create table t_stu_new_5(
id int(11) primary key auto_increment
) as (
select id,name from t_stu );desc t_stu_new_5;
MySQL(零基础)详解之DQL相关推荐
- 【C零基础详解】Part1:7-1 计算摄氏温度 (10分)【变量的输入和输出】
7-1 计算摄氏温度 (10分) 给定一个华氏温度F,本题要求编写程序,计算对应的摄氏温度C.计算公式:C=5×(F−32)/9.题目保证输入与输出均在整型范围内. 输入格式: 输入在一行中给出一个华 ...
- MySQL数据库基础详解
文章大纲 一.数据库简介 二.Mysql数据库简介 三.Mysql安装与服务启动(Windows版本) 四.Mysql图形化工具 五.Mysql存储引擎精讲 六.Mysql数据类型介绍 七.Mysql ...
- MySQL数据库基础详解(非原创)
文章大纲 一.数据库简介 二.Mysql数据库简介 三.Mysql安装与服务启动(Windows版本) 四.Mysql图形化工具 五.Mysql存储引擎精讲 六.Mysql数据类型介绍 七.Mysql ...
- Python零基础详解--商品详情、关键词搜索api
为了进行此平台API的调用,首先我们需要做下面几件事情. 1. 获取一个KEY. 2. 参考API文档里的接入方式和示例. 3.查看测试工具是否有需要的接口,响应实例的返回字段是否符合参数要求. 4. ...
- FWT(快速沃尔什变换)零基础详解qaq(ACM/OI)
1.前言(废话) 记得一年半之前做SRM518 Nim的时候还不知道FWT,当时自己用分治完美的水过去了.然后昨天的牛客有一道题,是说nim博弈中有n堆石子,请问最多取出多少堆石子可以让先手必败.当时 ...
- 思科ei ccie认证体系最新内容下一代编址IPV6技术最全面的基础详解 从零到精通必读
思科ei ccie认证体系最新内容下一代编址IPV6技术最全面的基础详解 从零到精通必读 IPv6(Internet Protocol Version 6,因特网协议版本6)是网络层协议的第二代标准协 ...
- MySQL字段类型详解
MySQL字段类型详解 2009-01-05 09:25 来源:泡菜博客 0个评论 分享文章 A- A+ 百度权重查询 词库网 网站监控 服务器监控 SEO监控 Swift编程语言教程 MySQL支持 ...
- 高并发架构系列:Redis缓存和MySQL数据一致性方案详解
需求起因 在高并发的业务场景下,数据库大多数情况都是用户并发访问最薄弱的环节.所以,就需要使用redis做一个缓冲操作,让请求先访问到redis,而不是直接访问MySQL等数据库. 这个业务场景,主要 ...
- MySQL主从同步详解与配置
https://zhuanlan.zhihu.com/p/335142300 MySQL主从同步详解与配置 第一部分[原理解析] * 应用背景* MySQL数据库自身提供的主从复制功能可以方便的实现数 ...
- 《MySQL安装流程详解》及《MySQL安装一直失败,重新安装显示已安装》
<MySQL安装流程详解>及<MySQL安装一直失败,重新安装显示已安装> 本文由博主经过查阅网上资料整理总结后编写,如存在错误或不恰当之处请留言以便更正,内容仅供大家参考学习 ...
最新文章
- oracle安装清单过不去,oracle 11g(二)安装过程
- Android 开发常用代码片段
- java题目不会做那么解答_有几道JAVA的题目不会做 哪位高手来解答一下!谢
- 对象集合中如何用对象的某个属性给对象排序?
- 深入理解PHP之数组(遍历顺序)
- 进程和线程不属于标准c语言,经典C语言面试题6:进程与线程的关系和区别
- Farthest points Sampling on 3D meshes with mesh kept based on diffusion distance
- ubuntu目录结构
- 谷歌linux浏览器下载文件夹在哪,如何查看谷歌浏览器下载的文件路径?
- C语言中期报告格式,本科论文中期报告范文_本科毕业论文中期报告模板(2)
- 支持断点续传的大文件传输协议
- 论文阅读--SAP-SSE: Protecting Search Patterns and Access Patterns in Searchable Symmetric Encryption
- 我叫mt4公会攻城战服务器维护中,我叫MT4工会攻城战攻略玩法详解[多图]
- 台式电脑组装机相关知识之主板篇
- Hangfire详解
- C:素数(质数)的判断以及输出
- Android Q访问公共外部存储受限
- python中取对数怎么表示_python中取对数
- Java+SSM酒店管理系统旅店管理(含源码+论文+答辩PPT等)
- 【WordPress】修改固定链接,文章链接
热门文章
- 关闭cidaemon进程的方法
- Web实时语音/视频聊天/文件传输
- 尚硅谷kylin单机版之安装kylin
- [经验]iOS开发-记录下在开发过程中遇到的问题的解决方案及经验总结-1
- 压力单位PSI,PSIG, PSIA的区别
- 根据地址查询经纬度Js
- DSP编程时 c_int00是什么内容
- python自动上传图片_Python+selenium自动上传博客图片至新浪微博相册
- php theexcerpt,WordPress:使用the_excerpt函数显示摘要信息
- 【Python表白小程序】七夕表白神器(赶紧收藏起来)