表:table是数据库的基本组成单元,所有的数据都是以表格的形式组织,目的是可读性强
一张表由若干行列组成,行称为数据/记录,列称为字段
row:行,每一行代表的是一条数据
column:列,又称字段,用于区分此段数据的含义,具备字段名、数据类型、相关约束等属性
SQL是数据库标准语法,根据不同的功能分为一下四类:
DQL:(数据查询语言)查询语句,对数据进行查询
DML:(数据操作语言)insert、delete、update,对表中的数据进行修改
DDL:(数据定义语言)create、drop、alter,对表结构进行增删改
TCL:(事务控制语言)commit提交事务,rollback事务回滚
DCL:(数据控制语言)grant授权、revoke撤销授权
登录MySQL
mysql -u[username] -p[password]
mysql -uroot -p123456
查看有哪些数据库
show databases;
创建数据库
create database myDatabase;
使用myDatabase数据库
use myDatabase;
查看当前数据库存在哪些表
show tables;
导入sql脚本数据
source [path for your file.sql]
source /usr/mysql/data.sql;
查看数据表结构
desc tableName;
数据查询语句 select
#查看当前所处的数据库
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;
比较运算查询
#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;#表示查询结果结果中,年龄按照升序排序,名字按照首字母降序排序(首字母相同则比较第二个字母,只懂啊比较结束)
分组函数自动忽略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最小值
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
一个完整的DQL怎么写?
select
字段,...
from
表名称
where
字段查询条件
group by
按照什么字段分组
having
在分组结果中增加过滤条件
order by
最后的结果排序
distinct关键字
#去除查询结果集中重复记录
select distinct age,name from tableName;
根据连接方式分为:内连接、外连接、全连接(很少用)
表别名:执行效率高,可读性好。
笛卡尔积现象,在两个表中,如果不加查询条件,得到的结果集等与A表的行数*B表的行数。
思考:如何避免笛卡尔积?避免笛卡尔积查询次数会变少吗?
使用条件查询避免笛卡尔积。
查询次数不会变少,因为要先把所有的结果都遍历出来才能进行过滤。
等值连接
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
过滤条件
什么是外连接,和内连接有什么区别?
内连接:假设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
过滤条件
既有左连接也有右连接
select
(select)
from
(select)
where
(select)
#查询年龄大于平均年龄的人员
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
#计算每个部门平均薪水等级
#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;
#找出每个员工所在的部门名称,要求显示员工名和部门名
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;
#将两张不相关的表联合在一起,得到的字段名称为第一个查询表的字段名,且两个表的查询字段数量一致
select ename from emp
union
select dname from deptno;
取结果集中的部分数据,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