连接查询
为防止数据冗余,会将有关系的数据放在不同的表中,表之间有关系,这也是关系型数据库的由来。
内连接
等值连接
连接条件是等量关系
查询每个员工的员工名和所在部门名
select e.ename,d.dname from emp e,dept d where e.deptno = d.deptno;
以上为92年的SQL语法,现在多使用92年的SQL语法,使用join on进行表连接
select e.ename,d.dname from emp e join dept d on e.deptno = d.deptno;
请读者自行尝试。
非等值连接
连接条件是非等值关系
查找每个员工的工资等级,显示员工名,薪资,薪资等级
select e.ename,e.sal,s.grade from emp e join salgrade s on e.sal between s.losal and hisal;
自连接
自己连自己
查询员工的上级领导,显示员工名、领导名(不必查出所有员工)
select e.ename,m.ename from emp e join emp m on e.mgr = m.empno;
注:join前省略了inner,读者可自行尝试
外连接
分为主表和副表,主要主表中的数据全部查询出来,当副表中的数据和主表的数据匹配不上,副表自动模拟出NULL与之匹配。
join前加left或right
左(外)连接
左表为主表
查询员工的上级领导,显示员工名、领导名(查出所有员工,没有领导时显示NULL)
select e.ename,m.ename from emp e left join emp m on e.mgr = m.empno;
注意,KING是大BOSS,没有领导,所以是NULL,另外,left和join之间省略了outer,读者可自行尝试。
右(外)连接
右表为主表
找出哪个部门没有员工
select d.* from emp e right join dept d on e.deptno = d.deptno where empno is null;
使用右连接,部门必全部查出来,如果没有员工,则员工号为NULL
当然,条条大路通罗马,也可以使用子查询。
select * from dept where deptno not in (select deptno from emp group by deptno);
多表连接
看成多次两表连接即可。
查询每个员工的员工名,部门名,工资等级
select e.ename,d.dname,s.grade from emp e join dept d on e.deptno = d.deptno join salgrade s on e.sal between s.losal and hisal;
子查询
where子句中
查询高于平均薪资的员工信息
select * from emp where sal > (select avg(sal) from emp);
可以看到,结果都是大于平均薪资的员工
from子句中
查询每个部门平均薪资所属的薪资等级
select t.*,s.grade from (select deptno,avg(sal) avgsal from emp group by deptno) t join salgrade s where t.avgsal between s.losal and s.hisal;
将上面的查询结果,当做临时表t,临时表t与salgrade表进行连接,连接条件是平均工资在最低和最高工资之间。
Select子句中
查询每个员工所在部门的名称,显示员工名和部门名
使用表连接的话可以这样写:
select e.ename,d.dname from emp e join dept d on e.deptno = d.deptno;
也可不进行表连接,写到select子句中
select e.ename,(select d.dname from dept d where e.deptno = d.deptno) from emp e;
Union查询
这个在SQL注入中是一种注入技巧
两个查询结果必须列数相同
查询工作岗位是SALESMAN和MANAGER的员工
select ename,job from emp where job = 'MANAGER' union select ename,job from emp where job = 'SALESMAN';
Limit(分页查询)
Mysql独有的,用于取结果的部分数据,sqlserver、Oracle中不能使用,Oracle中有rownum差不多。
limit [startIndex] length
- startIndex :起始位置,从0开始,默认为0
- length:个数
查询工资前5名的员工名和工资
select ename,sal from emp order by sal desc limit 0,5;
select ename,sal from emp order by sal desc limit 5;
每页显示pageSize条记录,pageNo从1开始,则
第pageNo页:?,pageSize ==> ? 为 (PageNo - 1)*pageSize,pageSize
例如,pageSize = 3,pageNo = 1, limit 0,3
DDL
Create
创建表
语法
CREATE TABLE 表名称 ( 列名称1 数据类型, 列名称2 数据类型, 列名称3 数据类型, .... )
常见字段类型
int:整型
bigint:长整型
float:浮点型
char:定长字符串
varchar:可变长字符串
date:日期类型
BLOB:(Binary Large Object,二进制大对象),存储 图片/视频 等流媒体信息
CLOB:(Character Large Object,字符大对象),
建立学生表t_student,学号 no,bigint类型,姓名 name,varchar类型,性别 sex char类型,班号 classno,varchar类型,生日 birth char类型
create table t_student( no bigint, name varchar(255), sex char(1), classno varchar(255), birth char(10) );
从其他表获取
create table table_name as select 语句;
创建emp1表, 仅包含emp表的ename和sal字段。
create table emp1 as select ename,sal from emp;
Drop
语法
drop table [if exists] table_name;
ALTER
使用图形化界面即可,例如Navicat 表右键->设计表,一般创建时很谨慎,设计好再创建,很少修改表结构。
DML
INSERT
语法
INSERT INTO table_name VALUES (值1, 值2,....),(值1, 值2,....),
我们也可以指定所要插入数据的列,这样,其他列就是默认值:
INSERT INTO table_name (列1, 列2,...) VALUES (值1, 值2,....),(值1, 值2,....)
insert into t_student values(1,'zhangsan','1','gaosan1ban','1996-11-20');
一次多行插入
insert into t_student values(2,'lisi','0','gaosan1ban','1996-10-20'),(3,'wangwu','1','gaosan1ban','1994-01-12');
从其他表插入
列,类型之类的要一样,很少用,提一下,不截图了。
insert into table_name select 语句;
创建dept1表与dept表数据一致,在dept1表后再插入一次dept表的所有内容
create table dept1 as select * from dept; insert into dept1 select * from dept;
UPDATE
语法
update table_name set 字段名1=值1,字段名2=值2,... [where 语句];
注意,没有条件,整张表全部更新。
将dept1表中部门编号为10的LOC字段改为BEIJING
update dept1 set loc = 'BEIJING ' where deptno = 10;
DELETE
语法
delete from table_name [where 子句];
没有条件全部删除
删除部门20的所有数据
delete from dept1 where deptno = 20;
大表删除数据
对于亿级及以上的大表,删除快,但无法回滚
语法
truncate table table_name;
删除表dept1
truncate table dept1;