MySQL-DQL

1、MySQL基础

1.1关键字

:table是数据库的基本组成单元,所有的数据都是以表格的形式组织,目的是可读性强

一张表由若干行列组成,行称为数据/记录,列称为字段

row:行,每一行代表的是一条数据

column:列,又称字段,用于区分此段数据的含义,具备字段名、数据类型、相关约束等属性

1.2SQL语句

SQL是数据库标准语法,根据不同的功能分为一下四类:

DQL:(数据查询语言)查询语句,对数据进行查询

DML:(数据操作语言)insert、delete、update,对表中的数据进行修改

DDL:(数据定义语言)create、drop、alter,对表结构进行增删改

TCL:(事务控制语言)commit提交事务,rollback事务回滚

DCL:(数据控制语言)grant授权、revoke撤销授权

1.3导入数据

  1. 登录MySQL

    mysql -u[username] -p[password]
    mysql -uroot -p123456
    
  2. 查看有哪些数据库

    show databases;
    
  3. 创建数据库

    create database myDatabase;
    
  4. 使用myDatabase数据库

    use myDatabase;
    
  5. 查看当前数据库存在哪些表

    show tables;
    
  6. 导入sql脚本数据

    source [path for your file.sql]
    source /usr/mysql/data.sql;
    
  7. 查看数据表结构

    desc tableName;
    

2、常用指令

2.1DQL

数据查询语句 select

2.1.1简单查询

#查看当前所处的数据库
select database();
#-----------------
#查看mysql version
select version();
#-----------------
#查看表的所有字段数据
select * from tableName;
#-----------------
#查看表的指定字段数据
select column_1,column_2,... from tableName;
#-----------------
#查看表的指定字段数据加入运算,并将字段名改成指定名称(注意:字符串应使用通用的单引号括起,mysql中不需要单引号也可以,但是其他数据库不一定支持。)
select column_1*10 (as) 'newName' from tableName;

2.1.2条件查询

比较运算查询

#sql语句格式  select 字段 from 表名 where 条件;
#可选条件 大于>,小于<,等于=,大于等于>=,小于等于<=,不等于<>/!=
#查找年龄大于30岁的员工
select name,age,birthday from user where age>30;
#查找年龄不等于30岁的员工
select name,age,birthday from user where age!=30;

逻辑运算查询

# ? and ? 同时符合条件
select name,age,birthday from user where age!=30 and name between 'A' and 'D';

# ? or ? 只要符合一个条件
select name,age,birthday from user where age!=30 or name='job';

#in 等同于多个or
select name,age,birthday from user where age in (20,30);#年龄等于20或30岁

#not in
select name,age,birthday from user where age not in (20,30);#年龄不等于20或不等于30岁

# ? and (? or ?) 联合使用,and 优先级比or高,所以此时or需要加括号提高优先级
select name,age,birthday from user where age!=30 and (birthday='19980802' or name='job');

范围查询

#between ? and ? 等同 >=? and <=?
select name,age,birthday from user where age between 12 and 30;#查询12到30岁之间的人员
#between 除了表示数字的范围,还可以表示字符串的范围
select name,age from user where name between 'A' and 'D';#查询名字开头字母A-D之间的人员
#in(?,?)

模糊查询

#like '%am_\_'  %表示任一多个字符,_表示一个字符,\表示转义
select name,age from user where name like '%O\T';#查询名字中包含A字符且以t结尾的名字 SCOTT 

NULL查询

在sql中null表示该字段什么也没有,为空(0不表示空)

#查询哪些人的津贴为NULL
select ename,sal,comm from user where comm = NULL;

#查询哪些人的津贴不为空(0.00表示不为空)
select ename,sal,comm from user where comm is not NULL;

#查询哪些人没有津帖
select ename,sal,comm from user where comm is not NULL or comm=0.00;

排序

# order by在所有的查询中,得到的结果都可以指定某个字段按照升序或降序排序,默认为升序
# 越靠前的排序字段作用越大,后一个字段是在第一字段无法完成排序的时候才启用后面的字段
select name,age,birthday from user where age!=30 or name='job' order by age asc,name desc;#表示查询结果结果中,年龄按照升序排序,名字按照首字母降序排序(首字母相同则比较第二个字母,只懂啊比较结束)

2.1.3分组函数

分组函数自动忽略NULL,如果NULL参与运算,结果一定是NULL,此时使用ifnull(可能为null的字段,设置默认的规则)

分组函数又称为多行处理函数,多行数据输入,输出一行结果

  • count 计数

    select count(*) from user;#计算总记录条数
    
    select count(age) from user;#统计某个字段不为null的数据总数量
    
  • sum求和

    select sum(age) from user;#计算总的年龄
    
    select (sal+ifnull(comm,0.00))*12 from user;#计算年薪,(基本薪资+补贴)*12如果comm为NULL则当作0.00
    
  • avg平均值

    select avg(age) from user;#计算平均年龄
    
  • max最大值

    
    
  • min最小值

2.1.4分组

group by /having

#group by 按照某个字段或某些字段分组
#执行顺序  where->group by ->分组函数
#如果缺省group by,表示整张表作为一个整体
select max(sal) from user;#找出所有岗位中的最高薪资
select max(sal) from user group by job;#找出每个岗位的最高薪资

#当使用group by时,select后面字段只能包含分组字段和分组函数字段
select name,max(sal) from user group by job;#此时name字段无意义,且在Oracle中会报错。


#多字段分组查询
select max(sal) from user group by depton,job;#找出每个部门,不同岗位的最高薪资

#找出不同部门的最高薪资,且薪资大于2900
#写法一效率最低,因为分组后包含了许多小于2900的无用数据
select max(sal),depton from uer group by depton hiving max(sal)>2900;

#写法二直接使用where过滤低于2900的薪资,数据量减少再参与分组
select max(sal),depton from user where sal>2900 group by depton;

#找出不同部门的平均薪资,且平均工资高于2900
select avg(sal),depton from uer group by depton hiving avg(sal)>2900;

#分组原则
#1、where 后面不能接分组函数
#2、where 尽量过滤一些条件数据
#3、如果where不能解决就使用hiving

2.1.4单表查询小结

一个完整的DQL怎么写?

select 
	字段,...
from
	表名称
where
	字段查询条件
group by
	按照什么字段分组
having
	在分组结果中增加过滤条件
order by
	最后的结果排序

2.1.5去重

distinct关键字

#去除查询结果集中重复记录
select distinct age,name from tableName;

2.1.6多表连接查询

根据连接方式分为:内连接、外连接、全连接(很少用)

表别名:执行效率高,可读性好。

笛卡尔积现象,在两个表中,如果不加查询条件,得到的结果集等与A表的行数*B表的行数。

思考:如何避免笛卡尔积?避免笛卡尔积查询次数会变少吗?

​ 使用条件查询避免笛卡尔积。

​ 查询次数不会变少,因为要先把所有的结果都遍历出来才能进行过滤。

2.1.6.1内连接 inner

  • 等值连接

    select 
    	a.字段,a.字段,b.字段
    from 
    	table1 a 
    (inner) join
    	table2 b 取表别名连接
    on
    	a.xx=b.xx 连接条件
    where
    	过滤条件
    
  • 非等值连接

    连接条件非等值关系

    select 
    	a.字段,a.字段,b.字段
    from 
    	table1 a 
    (inner) join
    	table2 b 取表别名连接
    on
    	a.xx between b.low and b.high
    where
    	过滤条件
    
  • 自连接

    一张表看成两张表,一张表中的不同字段存在关系

    select 
    	a.字段,a.字段,b.字段
    from 
    	table1 a 
    (inner) join
    	table1 b 取表别名连接
    on
    	a.xx=b.yy
    where
    	过滤条件
    

2.1.6.2外连接

什么是外连接,和内连接有什么区别?

​ 内连接:假设A和B和表进行连接,使用内连接的话,凡是A表和B表能够匹配上的记录查询出来,AB没有主副表之分

​ 外连接:假设A和B和表进行连接,使用外连接的话,AB两张表中有一张表为主表,另外一张表为副表,主要查询主表中的数据,捎带查询副表数据,如果副表中的数据没有和主表中的数据匹配上,副表自动模拟出一个null对应。

​ 左外连接与右外连接可以转化。

  • 左外连接

    select 
    	a.字段,a.字段,b.字段
    from 
    	table1 a #主表
    left (outer) join
    	table2 b #副表
    on
    	a.xx=b.xx
    where
    	过滤条件
    
  • 右外连接

    select 
    	a.字段,a.字段,b.字段
    from 
    	table2 b #主表 
    right (outer) join
    	table1 a #副表
    on
    	a.xx=b.xx
    where
    	过滤条件
    

2.1.6.3全连接

既有左连接也有右连接

2.1.7嵌套子查询

select
	(select)
from
	(select)
where
	(select)

2.1.7.1where后面嵌套子查询

#查询年龄大于平均年龄的人员
select * from user where age>(select avg(age) from user);
#步骤拆解
#1.得到平均年龄 select avg(age) from user --> 33.43
#2.select * from user where age>33.43

2.1.7.2from后面嵌套子查询

#计算每个部门平均薪水等级
#1.找出每个部门的平均薪水,按照部门编号分组,求sal的平均值
select deptno,avg(sal) avgsal from emp group by deptno;
#2.将以上查询结果作为临时表t,让t表与salgrade表连接
select 
	t.*,s.grade
from
	(select deptno,avg(sal) avgsal from emp group by deptno) t
join
	salgrade s
on 
	t.acgsal between s.losal and s.hisal;

2.1.7.3select后面嵌套子查询

#找出每个员工所在的部门名称,要求显示员工名和部门名
select
	e.ename,d.deptno
from
	emp e
join
	dept d
on 
	e.deptno=d.deptno;
#等效于
select 
	e.ename,(select d.dname from dept d where e.deptno=d.deptno) as dname
from
	emp e;


2.1.8union 查询

#将两张不相关的表联合在一起,得到的字段名称为第一个查询表的字段名,且两个表的查询字段数量一致
select ename from emp
union
select dname from deptno;

2.1.9 limit分页查询

取结果集中的部分数据,mysql特有,非通用sql语句。

#limit startindex,count
#取前五个数据据
select * from emp limit 0,5

#取第4到第9条数据
select * from emp limit 3,6

#通用标准分页sql
select * from emp limit (page-1)*pageSize,pageSize

你可能感兴趣的:(数据库#mysql)