案例:找出每一个员工的部门名称,要求显示员工名和部门名。 EMP表 +--------+--------+ | ename | deptno | +--------+--------+ | SMITH | 20 | | ALLEN | 30 | | WARD | 30 | | JONES | 20 | | MARTIN | 30 | | BLAKE | 30 | | CLARK | 10 | | SCOTT | 20 | | KING | 10 | | TURNER | 30 | | ADAMS | 20 | | JAMES | 30 | | FORD | 20 | | MILLER | 10 | +--------+--------+ DEPT表 +--------+------------+----------+ | DEPTNO | DNAME | LOC | +--------+------------+----------+ | 10 | ACCOUNTING | NEW YORK | | 20 | RESEARCH | DALLAS | | 30 | SALES | CHICAGO | | 40 | OPERATIONS | BOSTON | +--------+------------+----------+
select ename,dname from emp,dept; +--------+------------+ | ename | dname | +--------+------------+ | SMITH | ACCOUNTING | | SMITH | RESEARCH | | SMITH | SALES | | SMITH | OPERATIONS | | ALLEN | ACCOUNTING | | ALLEN | RESEARCH | | ALLEN | SALES | | ALLEN | OPERATIONS | ............ 56 rows in set (0.00 sec)
SQL92:(太老,不用了) // select // e.ename,d.dname // from // emp e, dept d // where // e.deptno = d.deptno;
SQL99:(常用的) select e.ename,d.dname from emp e join dept d on e.deptno = d.deptno;
// inner可以省略的,带着inner目的是可读性好一些。 //inner表明是内连接 select e.ename,d.dname from emp e inner join dept d on e.deptno = d.deptno; //条件是等量关系,所以叫等值连接 语法: ... A join B on 连接条件 where ... SQL99语法结构更清晰一些:表的连接条件和后来的where条件分离了。
+--------+------------+ | ename | dname | +--------+------------+ | CLARK | ACCOUNTING | | KING | ACCOUNTING | | MILLER | ACCOUNTING | | SMITH | RESEARCH | | JONES | RESEARCH | | SCOTT | RESEARCH | | ADAMS | RESEARCH | | FORD | RESEARCH | | ALLEN | SALES | | WARD | SALES | | MARTIN | SALES | | BLAKE | SALES | | TURNER | SALES | | JAMES | SALES | +--------+------------+
select e.ename,e.sal,s.grade from emp e join salgrade s on e.sal between s.losal and s.hisal;
select e.ename, s.grade from emp e join salgrade s on e.sal between s.losal and s.hisal; // inner可以省略 select e.ename,e.sal,s.grade from emp e inner join salgrade s on e.sal between s.losal and s.hisal;
+--------+---------+-------+ | ename | sal | grade | +--------+---------+-------+ | SMITH | 800.00 | 1 | | ALLEN | 1600.00 | 3 | | WARD | 1250.00 | 2 | | JONES | 2975.00 | 4 | | MARTIN | 1250.00 | 2 | | BLAKE | 2850.00 | 4 | | CLARK | 2450.00 | 4 | | SCOTT | 3000.00 | 4 | | KING | 5000.00 | 5 | | TURNER | 1500.00 | 3 | | ADAMS | 1100.00 | 1 | | JAMES | 950.00 | 1 | | FORD | 3000.00 | 4 | | MILLER | 1300.00 | 2 | +--------+---------+-------+
案例:找出每个员工的上级领导,要求显示员工名和对应的领导名。 mysql> select empno,ename,mgr from emp; emp a 员工表 +-------+--------+------+ | empno | ename | mgr | +-------+--------+------+ | 7369 | SMITH | 7902 | | 7499 | ALLEN | 7698 | | 7521 | WARD | 7698 | | 7566 | JONES | 7839 | | 7654 | MARTIN | 7698 | | 7698 | BLAKE | 7839 | | 7782 | CLARK | 7839 | | 7788 | SCOTT | 7566 | | 7839 | KING | NULL | | 7844 | TURNER | 7698 | | 7876 | ADAMS | 7788 | | 7900 | JAMES | 7698 | | 7902 | FORD | 7566 | | 7934 | MILLER | 7782 | +-------+--------+------+ emp b 领导表 +-------+--------+ | empno | ename | +-------+--------+ | 7566 | JONES | | 7698 | BLAKE | | 7782 | CLARK | | 7788 | SCOTT | | 7839 | KING | | 7902 | FORD | +-------+--------+
员工的领导编号 = 领导的员工编号
select a.ename as '员工名',b.ename as '领导名' from emp a inner join emp b on a.mgr = b.empno;
+--------+--------+ | 员工名 | 领导名 | +--------+--------+ | SMITH | FORD | | ALLEN | BLAKE | | WARD | BLAKE | | JONES | KING | | MARTIN | BLAKE | | BLAKE | KING | | CLARK | KING | | SCOTT | JONES | | TURNER | BLAKE | | ADAMS | SCOTT | | JAMES | BLAKE | | FORD | JONES | | MILLER | CLARK | +--------+--------+
emp a 员工表 +-------+--------+------+ | empno | ename | mgr | +-------+--------+------+ | 7369 | SMITH | 7902 | | 7499 | ALLEN | 7698 | | 7521 | WARD | 7698 | | 7566 | JONES | 7839 | | 7654 | MARTIN | 7698 | | 7698 | BLAKE | 7839 | | 7782 | CLARK | 7839 | | 7788 | SCOTT | 7566 | | 7839 | KING | NULL | | 7844 | TURNER | 7698 | | 7876 | ADAMS | 7788 | | 7900 | JAMES | 7698 | | 7902 | FORD | 7566 | | 7934 | MILLER | 7782 | +-------+--------+------+ emp b 领导表 +-------+--------+ | empno | ename | +-------+--------+ | 7566 | JONES | | 7698 | BLAKE | | 7782 | CLARK | | 7788 | SCOTT | | 7839 | KING | | 7902 | FORD | +-------+--------+
内连接: select a.ename '员工', b.ename '领导' from emp a join emp b on a.mgr = b.empno;
外连接:(左外连接/左连接) select a.ename '员工', b.ename '领导' from emp a left join emp b on a.mgr = b.empno;
// outer是可以省略的。 select a.ename '员工', b.ename '领导' from emp a left outer join emp b on a.mgr = b.empno;
外连接:(右外连接/右连接) select a.ename '员工', b.ename '领导' from emp b right join emp a on a.mgr = b.empno;
// outer可以省略。 select a.ename '员工', b.ename '领导' from emp b right outer join emp a on a.mgr = b.empno;
+--------+-------+ | 员工 | 领导 | +--------+-------+ | SMITH | FORD | | ALLEN | BLAKE | | WARD | BLAKE | | JONES | KING | | MARTIN | BLAKE | | BLAKE | KING | | CLARK | KING | | SCOTT | JONES | | KING | NULL | | TURNER | BLAKE | | ADAMS | SCOTT | | JAMES | BLAKE | | FORD | JONES | | MILLER | CLARK | +--------+-------+
注意,解释一下: .... A join B join C on ... 表示:A表和B表先进行表连接,连接之后A表继续和C表进行连接。
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 s.hisal; +--------+------------+-------+ | ename | dname | grade | +--------+------------+-------+ | SMITH | RESEARCH | 1 | | ALLEN | SALES | 3 | | WARD | SALES | 2 | | JONES | RESEARCH | 4 | | MARTIN | SALES | 2 | | BLAKE | SALES | 4 | | CLARK | ACCOUNTING | 4 | | SCOTT | RESEARCH | 4 | | KING | ACCOUNTING | 5 | | TURNER | SALES | 3 | | ADAMS | RESEARCH | 1 | | JAMES | SALES | 1 | | FORD | RESEARCH | 4 | | MILLER | ACCOUNTING | 2 | +--------+------------+-------+
案例:找出每一个员工的部门名称、工资等级、以及上级领导。 select e.ename '员工',d.dname,s.grade,e1.ename '领导' from emp e join dept d on e.deptno = d.deptno join salgrade s on e.sal between s.losal and s.hisal left join emp e1 on e.mgr = e1.empno;
+--------+------------+-------+-------+ | 员工 | dname | grade | 领导 | +--------+------------+-------+-------+ | SMITH | RESEARCH | 1 | FORD | | ALLEN | SALES | 3 | BLAKE | | WARD | SALES | 2 | BLAKE | | JONES | RESEARCH | 4 | KING | | MARTIN | SALES | 2 | BLAKE | | BLAKE | SALES | 4 | KING | | CLARK | ACCOUNTING | 4 | KING | | SCOTT | RESEARCH | 4 | JONES | | KING | ACCOUNTING | 5 | NULL | | TURNER | SALES | 3 | BLAKE | | ADAMS | RESEARCH | 1 | SCOTT | | JAMES | SALES | 1 | BLAKE | | FORD | RESEARCH | 4 | JONES | | MILLER | ACCOUNTING | 2 | CLARK | +--------+------------+-------+-------+
案例:找出每个部门平均薪水的等级。 第一步:找出每个部门平均薪水(按照部门编号分组,求sal的平均值) select deptno,avg(sal) as avgsal from emp group by deptno; +--------+-------------+ | deptno | avgsal | +--------+-------------+ | 10 | 2916.666667 | | 20 | 2175.000000 | | 30 | 1566.666667 | +--------+-------------+ 第二步:将以上的查询结果当做临时表t,让t表和salgrade s表连接,条件是:t.avgsal between s.losal and s.hisal select t.*,s.grade from (select deptno,avg(sal) as avgsal from emp group by deptno) t //当作一张临时表 join salgrade s on t.avgsal between s.losal and s.hisal;
案例:取出工资前5名的员工(思路:降序取前5个) select ename,sal from emp order by sal desc; 取前5个: select ename,sal from emp order by sal desc limit 0, 5; select ename,sal from emp order by sal desc limit 5;
5.4、limit是sql语句最后执行的一个环节:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
select 5 ... from 1 ... where 2 ... group by 3 ... having 4 ... order by 6 ... limit 7 ...; 1234567891011121314
5.5、案例:找出工资排名在第4到第9名的员工?
1 2 3 4 5 6 7 8 9 10 11 12
select ename,sal from emp order by sal desc limit 3,6; +--------+---------+ | ename | sal | +--------+---------+ | JONES | 2975.00 | | BLAKE | 2850.00 | | CLARK | 2450.00 | | ALLEN | 1600.00 | | TURNER | 1500.00 | | MILLER | 1300.00 | +--------+---------+ 1234567891011
语法格式: insert into 表名(字段名1,字段名2,字段名3,....) values(值1,值2,值3,....) 要求:字段的数量和值的数量相同,并且数据类型要对应相同。
insert into t_student(no,name,sex,classno,birth) values(1,'zhangsan','1','gaosan1ban'); ERROR 1136 (21S01): Column count doesn't match value count at row 1
insert into t_student(no,name,sex,classno,birth) values(1,'zhangsan','1','gaosan1ban', '1950-10-12');
mysql> select * from t_student; +------+----------+------+------------+------------+ | no | name | sex | classno | birth | +------+----------+------+------------+------------+ | 1 | zhangsan | 1 | gaosan1ban | 1950-10-12 | +------+----------+------+------------+------------+
insert into t_student(name,sex,classno,birth,no) values('lisi','1','gaosan1ban', '1950-10-12',2);
drop table if exists t_student; // 当这个表存在的话删除。 create table t_student( no bigint, name varchar(255), sex char(1) default 1, classno varchar(255), birth char(10) );
insert into t_student(name) values('zhangsan'); mysql> select * from t_student; +------+----------+------+---------+-------+ | no | name | sex | classno | birth | +------+----------+------+---------+-------+ | NULL | zhangsan | 1 | NULL | NULL | +------+----------+------+---------+-------+
1. 首先分组查询出帖子的评论个数 select replied_id, count(*) from t_comment group by replied_id
案例:将部门10的LOC修改为SHANGHAI,将部门名称修改为RENSHIBU update dept1 set loc = 'SHANGHAI', dname = 'RENSHIBU' where deptno = 10; mysql> select * from dept1; +--------+------------+----------+ | DEPTNO | DNAME | LOC | +--------+------------+----------+ | 10 | RENSHIBU | SHANGHAI | | 20 | RESEARCH | DALLAS | | 30 | SALES | CHICAGO | | 40 | OPERATIONS | BOSTON | | 10 | RENSHIBU | SHANGHAI | | 20 | RESEARCH | DALLAS | | 30 | SALES | CHICAGO | | 40 | OPERATIONS | BOSTON | +--------+------------+----------+
更新所有记录 update dept1 set loc = 'x', dname = 'y'; mysql> select * from dept1; +--------+-------+------+ | DEPTNO | DNAME | LOC | +--------+-------+------+ | 10 | y | x | | 20 | y | x | | 30 | y | x | | 40 | y | x | | 10 | y | x | | 20 | y | x | | 30 | y | x | | 40 | y | x | +--------+-------+------+
11、删除数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
删除表: drop table if exists t_student;
语法格式: delete from 表名 where 条件;
注意:没有条件全部删除。
删除10部门数据 delete from dept1 where deptno = 10;
删除所有记录 delete from dept1;
怎么删除大表中的数据?(重点) truncate table 表名; // 表被截断,不可回滚。永久丢失。 删除表? drop table 表名; // 这个通用。 drop table if exists 表名; // oracle不支持这种写法。
mysql> select *from t_teacher; +------+-----------+------+------+---------------+---------------------+ | no | name | sex | age | email | birth | +------+-----------+------+------+---------------+---------------------+ | 4 | teacher_1 | m | 26 | 534654@qq.com | 2022-06-28 16:43:25 | | 1 | teacher_1 | m | 26 | 5344@129.com | 2022-06-28 16:44:46 | | 2 | Name | m | 27 | 2334@129.com | 2022-06-28 16:44:46 | | 3 | teacher_3 | m | 28 | 3264@129.com | 2022-06-28 16:44:46 | +------+-----------+------+------+---------------+---------------------+ 4 rows in set (0.00 sec)
mysql> delete from t_student where no=3; Query OK, 0 rows affected (0.00 sec)
mysql> select name,age, email from t_teacher where age between 20 and 50 order by no desc; +-----------+------+---------------+ | name | age | email | +-----------+------+---------------+ | teacher_1 | 26 | 534654@qq.com | | teacher_3 | 28 | 3264@129.com | | Name | 27 | 2334@129.com | | teacher_1 | 26 | 5344@129.com | +-----------+------+---------------+ 4 rows in set (0.00 sec)
drop table if exists t_user; create table t_user( id int, username varchar(255) not null, password varchar(255) ); insert into t_user(id,password) values(1,'123'); ERROR 1364 (HY000): Field 'username' doesn't have a default value
insert into t_user(id,username,password) values(1,'lisi','123');