【MYSQL】DQL
MQSQL—DQL
目录
- MQSQL—DQL
- sql分类
- sql常用命令
- 案例数据准备
- 一、单表查询
- 1.简单查询
- 2.条件查询
- 3.排序order by
- 4.数据处理函数
- 5.分组处理函数
- 6.分组查询
- 二、多表查询
- 1.连接查询:
- (1)笛卡尔积现象:
- (2)内连接查询:
- <1>等值连接:
- <2>非等值连接:
- <3>自连接:
- (3)外连接查询:
- <1>右外连接/右连接:
- <2>左外连接/左连接:
- (4)多表连接:
- 2.子查询:
- (1)where中的子查询:
- (2)from中的子查询:
- (3)select中的子查询:
- 3.distinct去除重复记录:
- 4.union合并查询结果集
- 5.limit取子集
sql分类
DQL:数据库查询语言(select)
DML:数据操作语言(对表中的数据进行insert增、delete删、update改)
DDL:数据定义语言(create、drop、alter都是DDL)
TCL:事务控制语言(事务提交commit、回滚rollback)
DCL:数据控制语言(授权grant、撤销权限revoke)
sql常用命令
mysql登录(显示密码):mysql -uroot -p123456
mysql登录(隐藏密码):mysql -uroot -p
exit,退出mysql
describe/desc mysql,查看表结构
select version,查看数据库版本号
select database(),查看使用的是哪个数据库
show databases;,查看所有数据库
注意:sql语句不区分大小写
案例数据准备
DROP TABLE IF EXISTS EMP;
DROP TABLE IF EXISTS DEPT;
DROP TABLE IF EXISTS SALGRADE;CREATE TABLE DEPT(DEPTNO int(2) not null,DNAME VARCHAR(14) ,LOC VARCHAR(13),primary key (DEPTNO));
CREATE TABLE EMP(EMPNO int(4) not null,ENAME VARCHAR(10),JOB VARCHAR(9),MGR INT(4),HIREDATE DATE DEFAULT NULL,SAL DOUBLE(7,2),COMM DOUBLE(7,2),primary key (EMPNO),DEPTNO INT(2) );CREATE TABLE SALGRADE(GRADE INT,LOSAL INT,HISAL INT );INSERT INTO DEPT ( DEPTNO, DNAME, LOC ) VALUES (
10, 'ACCOUNTING', 'NEW YORK');
INSERT INTO DEPT ( DEPTNO, DNAME, LOC ) VALUES (
20, 'RESEARCH', 'DALLAS');
INSERT INTO DEPT ( DEPTNO, DNAME, LOC ) VALUES (
30, 'SALES', 'CHICAGO');
INSERT INTO DEPT ( DEPTNO, DNAME, LOC ) VALUES (
40, 'OPERATIONS', 'BOSTON');
commit;INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO ) VALUES (
7369, 'SMITH', 'CLERK', 7902, '1980-12-17', 800, NULL, 20);
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO ) VALUES (
7499, 'ALLEN', 'SALESMAN', 7698, '1981-02-20', 1600, 300, 30);
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO ) VALUES (
7521, 'WARD', 'SALESMAN', 7698, '1981-02-22', 1250, 500, 30);
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO ) VALUES (
7566, 'JONES', 'MANAGER', 7839, '1981-04-02', 2975, NULL, 20);
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO ) VALUES (
7654, 'MARTIN', 'SALESMAN', 7698, '1981-09-28', 1250, 1400, 30);
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO ) VALUES (
7698, 'BLAKE', 'MANAGER', 7839, '1981-05-01', 2850, NULL, 30);
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO ) VALUES (
7782, 'CLARK', 'MANAGER', 7839, '1981-06-09', 2450, NULL, 10);
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO ) VALUES (
7788, 'SCOTT', 'ANALYST', 7566, '1987-04-19', 3000, NULL, 20);
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO ) VALUES (
7839, 'KING', 'PRESIDENT', NULL, '1981-11-17', 5000, NULL, 10);
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO ) VALUES (
7844, 'TURNER', 'SALESMAN', 7698, '1981-09-08', 1500, 0, 30);
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO ) VALUES (
7876, 'ADAMS', 'CLERK', 7788, '1987-05-23', 1100, NULL, 20);
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO ) VALUES (
7900, 'JAMES', 'CLERK', 7698, '1981-12-03', 950, NULL, 30);
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO ) VALUES (
7902, 'FORD', 'ANALYST', 7566, '1981-12-03', 3000, NULL, 20);
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO ) VALUES (
7934, 'MILLER', 'CLERK', 7782, '1982-01-23', 1300, NULL, 10);
commit;INSERT INTO SALGRADE ( GRADE, LOSAL, HISAL ) VALUES (
1, 700, 1200);
INSERT INTO SALGRADE ( GRADE, LOSAL, HISAL ) VALUES (
2, 1201, 1400);
INSERT INTO SALGRADE ( GRADE, LOSAL, HISAL ) VALUES (
3, 1401, 2000);
INSERT INTO SALGRADE ( GRADE, LOSAL, HISAL ) VALUES (
4, 2001, 3000);
INSERT INTO SALGRADE ( GRADE, LOSAL, HISAL ) VALUES (
5, 3001, 9999);
commit;
一、单表查询
1.简单查询
命令 | 说明 |
---|---|
select 字段名 from 表名 | 查询一个字段 |
select 字段1, 字段2 from 表名 | 查询多个字段 |
select * from 表名 | 查询所有字段 |
字段名 as 别名 | 给查询的列起别名,显示别名不作修改(使用空格可代替省略) |
注意:在数据库中字符串中使用 ‘ 单引号 ’ 括起来
2.条件查询
select字段1, 字段2, 字段3
from表名
where条件;
常见条件符号 | 说明 |
---|---|
= | 等于 |
<>、!= | 不等于 |
<、<=、>、>= | 略 |
between … and … | 等价于 >= and <= |
is、is not | 是否为null的判断 |
and、or | and的 优先级 比or更高 |
in、not in | 等价于or、= |
like | 模糊查询 |
\ | 转义字符 |
% | 模糊匹配 |
注意:在数据库中null不能使用等号判断,必须使用 var is null;var is not null;
3.排序order by
- 1.升序排序(默认)
select字段1, 字段2, 字段3
from表名
order by字段n (asc);
- 2.降序排序
select字段1, 字段2, 字段3
from表名
order by字段n desc;
- 3.多字段排序(只有字段i相等才启用字段i+1)
select字段1, 字段2, 字段3
from表名
order by字段i desc, 字段i+1 desc;
4.数据处理函数
数据处理函数又称单行处理函数(一个输入对应一个输出)
单行处理函数 | 说明 |
---|---|
lower、upper | 大小写转换 |
substr | 取子串(起始下标从1开始,非0) |
length | 取长度 |
trim | 去空格 |
concat | 字符串拼接 |
round()、rand() | 四舍五入、随机数 |
ifnull | 空处理函数 |
注意:null只要参与运算,最终的结果一定为null
5.分组处理函数
分组处理函数又称多行处理函数(多个输入对应一个输出)
多行处理函数 | 说明 |
---|---|
count | 计数 |
sum | 求和 |
avg | 求平均 |
max | 最大值 |
min | 最小值 |
注意:
- 分组函数必须先进行分组(默认整张表为一组数据),然后才能使用
- 分组函数不能直接使用在where子句中【注意】
6.分组查询
先对数据进行分组,然后对每一组的数据进行操作、计算
select...
from...
where...
group by...
having...
order by...
固定的执行顺序:
- from:先从对应表中查询数据
- where:条件查询
- group by:根据限制进行分组
- having:使用having子句继续筛选
- select:查询结果
- order by:进行分组处理
- limit
注意:在一条select语句中如果有group by语句时,select后面只能有参加分组的字段、以及分组的函数,其他一律不能添加。
练习1-1:找出每个部门,不同工作岗位的最高薪资?
解题关键:将两个字段联合成一个字段,进行查看(两个字段联合分组)。
selectdeptno, job, max(sal)
fromemp
group bydeptno, job;
补充:使用having子句可以对分组之后的数据,进行进一步过滤(where和having优先使用where)
二、多表查询
1.连接查询:
从一张表中单独查询称为单表查询,
emp表和dept表联合起来查询数据,从emp表中取员工名字,从dept表中取部门名字,称为跨表查询。
多张表联合起来从中查询数据,称为连接查询。
(1)笛卡尔积现象:
select ename, dname from emp, dept;
result1:当两表进行连接查询时,无任何条件限制时,最后查询出的结果条数为两张表条数的乘积,被笛卡尔积现象(4 * 14 = 56)
selectename, dname
fromemp, dept
whereemp.deptno = dept.deptno;
result2:当两表进行连接查询时,有限制条件时对笛卡尔积的结果进行了筛选(14条)。
注意:在添加限制条件之后,虽然查询结果减少了(54->14),但查询匹配的次数仍然没有减少。可以对查询代码进行优化如下:
selectemp.ename, dept.dname fromemp, dept whereemp.deptno = dept.deptno;
可以使用别名操作进一步简化sql语句(表的连接查询都需要使用别名简化):
selecte.ename, d.dname fromemp e, dept d wheree.deptno = d.deptno;
查询结果都是一样的效果,但查询效率得到了提升。
总结:通过笛卡尔积现象得出,表的连接次数越多效率越低,应尽量减少表的连接次数。
(2)内连接查询:
内连接主要包括有等值连接、非等值连接和自连接。
<1>等值连接:
两表查询时约束条件为等值关系,故称为等值连接。
案例2-1:查询每个员工所在的部门名称,显示员工名和部门名称?
#sql92语法
selecte.ename, d.dname
fromemp e, dept d
wheree.deptno = d.deptno;#sql99语法
selecte.ename, d.dname
fromemp e
(inner) joindept d
one.deptno = d.deptno;
注意:
- sql92语法:结构不清晰,表的连接条件和后期进一步筛选的条件都放到了where的后面。
- sql99语法:表连接的条件是独立的,如果需要对连接的结果进行进一步筛选,再后继续添加where即可。
<2>非等值连接:
两表查询时约束条件不是一个等量关系,则称为非等值连接。
案例2-2:找出每个员工的薪资等级,要求显示员工名、薪资、薪资等级?
selecte.ename, e.sal, s.grade
fromemp e
joinsalgrade s
one.sal between s.losal and s.hisal;
<3>自连接:
案例2-3:查询员工的上级领导,要求显示员工名和对应的领导名?
#内连接之自连接:技巧一张表看作两张表
selecta.ename as '员工名', b.ename as '领导名'
fromemp a
joinemp b
ona.mgr = b.empno; -- 员工的领导编号等于领导的员工编号
(3)外连接查询:
<1>右外连接/右连接:
将右边表的数据全部查询出来,捎带着关联查询左边的表。
#右外连接
selecte.ename, d.dname
fromemp e right join dept d
one.deptno = d.deptno;# right的含义:表示将join关键字右边的表看成主表,主要是为了将右边表的数据全部查询出来,捎带着关联查询左边的表
注意:内连接与外连接的区别:在外连接中两张表产生了主次关系,在内连接中两张表是平等的(没有主次关系)。
<2>左外连接/左连接:
将左边表的数据全部查询出来,捎带着关联查询右边的表。
#左外连接
selecte.ename, d.dname
fromdept d left join emp e
one.deptno = d.deptno;
注意:外连接的查询结果条数一定大于内连接的查询结果条数。
案例2-4:查询每个员工的上机领导,要求显示所有员工的名字和领导名?
# 查询每个员工的上机领导,要求显示所有员工的名字和领导名
-- select
-- a.ename as '员工名', b.ename as '领导名'
-- from
-- emp a
-- join
-- emp b
-- on
-- a.mgr = b.empno;
selecta.ename as '员工名', b.ename as '领导名'
fromemp a
left joinemp b
ona.mgr = b.empno;
(4)多表连接:
多表连接语法如下:
select...
froma
joinb
ona与b内连接的限制条件
joinc
ona和c内连接的限值条件
right joind
ona和d右外连接的限值条件
注意:一条sql中内连接和外连接可以混合出现。
案例2-5:找出每个员工的部门名称以及工资等级,要求显示员工名、部门名称、薪资、薪资等级?
# 3.多表连接
selecte.ename, e.sal, d.dname, s.grade
fromemp e
joindept d
one.deptno = d.deptno
joinsalgrade s
one.sal between s.losal and s.hisal;
案例2-6:找出每个员工的部门名称以及工资等级,还有上级领导。要求显示员工名、领导名、部门名称、薪资、薪资等级?(增加表)
selecte.ename, e.sal, d.dname, s.grade, l.ename
fromemp e
joindept d
one.deptno = d.deptno
joinsalgrade s
one.sal between s.losal and s.hisal
left joinemp l
on e.mgr = l.empno;
2.子查询:
select语句中嵌套着子查询,被嵌套的select语句称为子查询。
select...(select)...
from...(select)...
where...(select)...
(1)where中的子查询:
案例2-7:找出比最低工资高的员工姓名和工资?
selectename, sal
fromemp
wheresal > min(sal);
注意:分组函数不能直接使用在where子句中【注意】
selectmin(sal)
from emp;
selectename, sal
fromemp
wheresal > 800;
selectename, sal
fromemp
wheresal > ( select min(sal) from emp );
(2)from中的子查询:
解题技巧:from后面的子查询,可以将子查询的查询结果当做一张临时表。
案例2-8:找出每个岗位的平均工资的薪资等级?
- step1:找出每个岗位的平均工资(按照岗位求平均值)
selectjob, avg(sal)
fromemp
group byjob;
- step2:克服心理障碍,把以上查询的结果当做一张完整的数据表进行下一步处理。
下一步处理,将t表与salgrade表进行表的连接查询,查询条件为:avg(sal) between s.losal and s.hisal
selectt.*, s.grade
fromt
joinsalgrade s
onavg(sal) between s.losal and s.hisal;
- step3:将构建的虚拟t表带入得到最终的sql语句
selectt.*, s.grade
from(select job, avg(sal) as avgsal from emp group by job) as t
joinsalgrade s
ont.avgsal between s.losal and s.hisal;
(3)select中的子查询:
注意:该内容了解即可
案例2-9:找出每个员工的部门名称,要求显示员工名、部门名?
selecte.ename, (select d.dname from dept d where e.deptno = d.deptno)
fromemp e;
select e.ename, dname
fromemp e, dept d
wheree.deptno = d.deptno;
注意:对于select后面的子查询,子查询只能一次返回1条结果,否则报错
3.distinct去除重复记录:
语法:distinct 字段
select distinct job from emp;
select distinct job, deptno from emp;
distince出现在所有字段前方,表示后面所有的字段联合起来,再去除重复记录。
4.union合并查询结果集
案例2-10:查询工作岗位是MANAGER和SALESMAN的员工?
#写法1:or
selecte.ename, e.job
fromemp e
wheree.job = 'MANAGER' or e.job = 'SALESMAN';
#写法2:in
selecte.ename, e.job
fromemp e
wheree.job in ('MANAGER', 'SALESMAN');
select e.ename, e.job from emp e where e.job = 'MANAGER'
union
select e.ename, e.job from emp e where e.job = 'SALESMAN';
注意:
- union效率更高,对于表的连接每次匹配满足笛卡尔积,但是union不仅减少了匹配次数,并还能够完成两个结果集的拼接。
- union在进行结果集合并的时候,要求两个结果集的列数必须相同。
- union在进行结果集合并的时候,oracle要求两个结果集的列数据类型必须相同(mysql不要求)。
5.limit取子集
limit是将查询结果集的一部分取出来,通常使用在网页的分页查询中。
注意:分页的作用是为了提高用户体验。
limit语法:limit startIndex, length
;(起始下标为0)
缺省语法:limit length
例如:按照薪资降序,取出排名在前5名的员工?
selectename, sal
fromemp
order bysal desc
limit 0, 5;
注意:
- 在mysql中,limit必须在order by之后执行。
- limit应用分页:若每页显示pageSize条记录,则第pageNo页为:
limit (pageNo - 1) * pageSize, pageSize;
【MYSQL】DQL相关推荐
- 【Mysql】DQL语法及其使用
DQL 一,DQL-语法 二,DQL-操作语句 1,DQL基本查询 (1),查询多个字段 (2),设置别名 2,条件查询 3,聚合函数 4,分组函数 5,排序查询 6,分页查询 三,DQL案例 四,D ...
- 【MySQL】黑马教程MySQL数据库 MySQL基础(一)
文章目录 [MySQL]黑马教程MySQL数据库 | MySQL基础(一) MySQL启动 MySQL客户端连接 MySQL数据模型 SQL SQL分类 DDL 表操作-查询 表操作-创建 表操作-数 ...
- PHP mysql数据迁移,【MySQL】迁移数据目录php-php教程
move dir # mv /var/libmysql /mnt/data/ vi /etc/my.cnf [mysqld] // 服务器端 datadir=/mnt/data/mysql socke ...
- shell实行mysql语句_【Mysql】shell运行mysql的sql语句_MySQL
bitsCN.com [Mysql]shell运行mysql的sql语句 shell本身是一种脚本语言,所以不能像java一样通过api去连接数据库.shell还是要借助mysql本身的一些运行脚本才 ...
- 【MySQL】ERROR 1045 (28000): Access denied for user的解决方法
[MySQL]ERROR 1045 (28000): Access denied for user的解决方法 参考文章: (1)[MySQL]ERROR 1045 (28000): Access de ...
- mysql8自定义安装位置_【MySQL】Windows10:MySQL 8 自定义路径安装
目录 一.MySQL官网下载 二.MySQL安装 三.mysql常用登录和快捷进入cmd操作 一.MySQL官网下载 (一)MySQL下载地址:https://dev.mysql.com/downlo ...
- 【MySQL】MHA部署与MasterFailover代码分析
[MySQL]MHA部署与MasterFailover代码分析 官网:https://code.google.com/p/mysql-master-ha/ 参考:http://blog.csdn.ne ...
- 【MySQl】MyISAM和InnoDB索引对比
[MySQl]MyISAM和InnoDB索引对比 部分内容转自:http://www.2cto.com/database/201211/172380.html 比较好的文章:http://www.cn ...
- 阿里巴巴对Java编程【Mysql】的规约
转载自 阿里巴巴对Java编程[Mysql]的规约 建表规约 1. [强制]表达是与否概念的字段,必须使用 is _ xxx 的方式命名,数据类型是 unsigned tinyint( 1 表示是,0 ...
最新文章
- 【好用的.vimrc】支持vim语法高亮,保留上一次编辑内容,记住位置等配置
- php 提取登录QQ,php QQ登录
- PHP钩子的简单介绍
- js 正则判断用户是否输入表情
- 30个Oracle语句优化规则详解(1)
- 2018/12/06 L1-022 L1-022 奇偶分家 Java
- while语句 ///do...while语句/// for语句/// foreach语句
- 《黑马程序员 MySQL数据库入门到精通,从MySQL安装到MySQL高级、MySQL优化全囊括》——学习笔记基础篇
- Java面试题(全)
- 深入了解JVM的底层原理
- 软考真题答案-2021年11月系统集成项目管理工程师上午题(一)
- 区别python中list()和tolist()的区别
- java获取outlook 日历,Outlook 日历 API 概述
- V2X方案之OBU介绍
- photoshop---压缩图片大小/给人物换衣服
- 小众浏览器测评 | 星愿 | 百分cent | Vivaldi | Brave
- html css特效,15个超酷的CSS3代码特效展示
- Win7环境安装Anaconda
- 并发策略-CAS算法
- Unity游戏设计与实现 南梦宫一线程序员的开发实例pdf