SQL语句练习

首先建表

SET FOREIGN_KEY_CHECKS=0;
#建立数据表bonus
drop table if exists `bonus`;
create table `bonus`(
`ENAME` varchar(10) not null default '',
`JOB` varchar(9) default null,
`SAL` bigint(22) default null,
`COMM` bigint(22) default null,
PRIMARY KEY (`ENAME`)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;

#建立数据表dept
drop table if exists `dept`;
create table `dept`(
`DEPTNO` decimal(2,0) not null default '0',
`DNAME` varchar(14) default null,
`LOC` varchar(13) default null,
PRIMARY KEY (`DEPTNO`),
UNIQUE KEY `PK_DEPT` (`DEPTNO`)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
#插入数据
insert into `dept` values('10','ACCOUNTING','NEW YORK');
insert into `dept` values('20','RESEARCH','DALLAS');    
insert into `dept` values('30','SALES','CHICAGO');
insert into `dept` values('40','OPERATIONS','BOSTON');

#建立数据表emp
drop table if exists `emp`;
create table `emp`(
`EMPNO` decimal(4,0) not null default '0',
`ENAME` varchar(10) default null,
`JOB` varchar(9) default null,
`MGR` decimal(4,0) default null,
`HIREDATE` datetime default null,
`SAL` decimal(7,2) default null,
`COMM` decimal(7,2) default null,
`DEPTNO` decimal(2,0) default null,
PRIMARY KEY (`EMPNO`),
UNIQUE KEY `PK_EMP` (`EMPNO`)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
#插入数据
INSERT INTO `emp` VALUES ('7369', 'SMITH', 'CLERK', '7902', '1980-12-17 00:00:00', '800.00', null, '20');
INSERT INTO `emp` VALUES ('7499', 'ALLEN', 'SALESMAN', '7698', '1981-02-20 00:00:00', '1600.00', '300.00', '30');
INSERT INTO `emp` VALUES ('7521', 'WARD', 'SALESMAN', '7698', '1981-02-22 00:00:00', '1250.00', '500.00', '30');
INSERT INTO `emp` VALUES ('7566', 'JONES', 'MANAGER', '7839', '1981-04-02 00:00:00', '2975.00', null, '20');
INSERT INTO `emp` VALUES ('7654', 'MARTIN', 'SALESMAN', '7698', '1981-09-28 00:00:00', '1250.00', '1400.00', '30');
INSERT INTO `emp` VALUES ('7698', 'BLAKE', 'MANAGER', '7839', '1981-05-01 00:00:00', '2850.00', null, '30');
INSERT INTO `emp` VALUES ('7782', 'CLARK', 'MANAGER', '7839', '1981-06-09 00:00:00', '2450.00', null, '10');
INSERT INTO `emp` VALUES ('7788', 'SCOTT', 'ANALYST', '7566', '1987-04-19 00:00:00', '3000.00', null, '20');
INSERT INTO `emp` VALUES ('7839', 'KING', 'PRESIDENT', null, '1981-11-17 00:00:00', '5000.00', null, '10');
INSERT INTO `emp` VALUES ('7844', 'TURNER', 'SALESMAN', '7698', '1981-09-08 00:00:00', '1500.00', '0.00', '30');
INSERT INTO `emp` VALUES ('7876', 'ADAMS', 'CLERK', '7788', '1987-05-23 00:00:00', '1100.00', null, '20');
INSERT INTO `emp` VALUES ('7900', 'JAMES', 'CLERK', '7698', '1981-12-03 00:00:00', '950.00', null, '30');
INSERT INTO `emp` VALUES ('7902', 'FORD', 'ANALYST', '7566', '1981-12-03 00:00:00', '3000.00', null, '20');
INSERT INTO `emp` VALUES ('7934', 'MILLER', 'CLERK', '7782', '1982-01-23 00:00:00', '1300.00', null, '10');

#建立数据表 salgrade
drop table if exists `salgrade`;
create table `salgrade`(
`GRADE` bigint(22) not null default '0',
`LOSAL` bigint(22) default null,
`HISAL` bigint(22) default null,
PRIMARY KEY (`GRADE`)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
#插入数据
insert into `salgrade` values ('1','700','1200');
insert into `salgrade` values('2','1201','1400');
insert into `salgrade` values('3','1401','2000');
insert into `salgrade` values('4','2001','3000');
insert into `salgrade` values('5','3001','9999');

建立的表如下

mysql> show tables;
+---------------------+
| Tables_in_couchbase |
+---------------------+
| bonus               |
| dept                |
| emp                 |
| salgrade            |
+---------------------+
mysql> select * from dept;
+--------+------------+----------+
| DEPTNO | DNAME      | LOC      |
+--------+------------+----------+
|     10 | ACCOUNTING | NEW YORK |
|     20 | RESEARCH   | DALLAS   |
|     30 | SALES      | CHICAGO  |
|     40 | OPERATIONS | BOSTON   |
+--------+------------+----------+
mysql> select * from emp;
+-------+--------+-----------+------+---------------------+---------+---------+--------+
| EMPNO | ENAME  | JOB       | MGR  | HIREDATE            | SAL     | COMM    | DEPTNO |
+-------+--------+-----------+------+---------------------+---------+---------+--------+
|  7369 | SMITH  | CLERK     | 7902 | 1980-12-17 00:00:00 |  800.00 |    NULL |     20 |
|  7499 | ALLEN  | SALESMAN  | 7698 | 1981-02-20 00:00:00 | 1600.00 |  300.00 |     30 |
|  7521 | WARD   | SALESMAN  | 7698 | 1981-02-22 00:00:00 | 1250.00 |  500.00 |     30 |
|  7566 | JONES  | MANAGER   | 7839 | 1981-04-02 00:00:00 | 2975.00 |    NULL |     20 |
|  7654 | MARTIN | SALESMAN  | 7698 | 1981-09-28 00:00:00 | 1250.00 | 1400.00 |     30 |
|  7698 | BLAKE  | MANAGER   | 7839 | 1981-05-01 00:00:00 | 2850.00 |    NULL |     30 |
|  7782 | CLARK  | MANAGER   | 7839 | 1981-06-09 00:00:00 | 2450.00 |    NULL |     10 |
|  7788 | SCOTT  | ANALYST   | 7566 | 1987-04-19 00:00:00 | 3000.00 |    NULL |     20 |
|  7839 | KING   | PRESIDENT | NULL | 1981-11-17 00:00:00 | 5000.00 |    NULL |     10 |
|  7844 | TURNER | SALESMAN  | 7698 | 1981-09-08 00:00:00 | 1500.00 |    0.00 |     30 |
|  7876 | ADAMS  | CLERK     | 7788 | 1987-05-23 00:00:00 | 1100.00 |    NULL |     20 |
|  7900 | JAMES  | CLERK     | 7698 | 1981-12-03 00:00:00 |  950.00 |    NULL |     30 |
|  7902 | FORD   | ANALYST   | 7566 | 1981-12-03 00:00:00 | 3000.00 |    NULL |     20 |
|  7934 | MILLER | CLERK     | 7782 | 1982-01-23 00:00:00 | 1300.00 |    NULL |     10 |
+-------+--------+-----------+------+---------------------+---------+---------+--------+
mysql> select * from salgrade;
+-------+-------+-------+
| GRADE | LOSAL | HISAL |
+-------+-------+-------+
|     1 |   700 |  1200 |
|     2 |  1201 |  1400 |
|     3 |  1401 |  2000 |
|     4 |  2001 |  3000 |
|     5 |  3001 |  9999 |
+-------+-------+-------+
  • 列出至少有一个员工的所有部门的部门编号,部门名称
select dept.deptno,dname from emp,dept where dept.deptno=emp.deptno;
select emp.deptno,dname from emp left join dept on dept.deptno=emp.deptno;
  • 列出薪资比"SMITH"多的所有员工的编号和名称
select empno,ename from emp where sal>(select sal from emp where ename='SMITH');
  • 列出所有员工的姓名和其直接上级的姓名
select table1.ename,table2.ename from emp table1 left join emp table2 on table1.mgr=table2.empno;
  • 列出受雇日期早于其直接上级的所有员工的编号,姓名,部门名称
select emp1.empno,emp1.ename,dname from emp emp1 
join emp emp2 on emp1.mgr=emp2.empno and emp1.hiredate
  • 列出部门名称和这些部门员工的所有信息,同时列出那些没有员工的部门
select dname,emp.* from dept left join emp on emp.deptno=dept.deptno;
  • 列出所有"CLERK"职位的人名,部门名,以及部门人数
select ename,dname,cou from emp
join dept on dept.deptno=emp.deptno and job='CLERK'
join (select count(*) cou,deptno from emp group by deptno) table1 on table1.deptno=emp.deptno;
  • 列出最低薪资大于1500的各种工作和从事此工作的人数
select job,count(empno) from emp group by job having min(sal)>1500;
  • 列出非主管的工作以及各个工作的平均薪资
select job,avg(sal) from emp where job!='PRESIDENT' group by job;
  • 列出工作为"CLERK"的员工的姓名
select ename from emp where job='CLERK';
  • 列出在部门“SALES”(销售部)工作的员工的姓名
select ename from emp join dept on dept.deptno=emp.deptno and dname='SALES';
  • 列出薪金高于公司平均薪金的所有员工的名字,所在部门,上级领导的名字,公司的工资等级
select table1.ename,dname, emp.ename manager, grade  from
(select ename,sal,deptno,mgr from emp where sal>(select avg(sal) from emp))table1
left join dept on table1.deptno=dept.DEPTNO
left join emp on table1.mgr =emp.empno
left join salgrade on table1.sal >= losal and table1.sal<=hisal;
  • 列出与“SCOTT”从事相同工作的所有员工的名字及部门名称
select table1.ename,dname from dept join
(select ename,deptno from emp where job=(select job from emp where ename='SCOTT') and ename!='SCOTT') table1
on table1.deptno=dept.deptno;
  • 列出薪金等于部门30中员工的薪金的所有员工的姓名和薪金
select ename,sal from emp where sal in (select sal from emp where deptno=30);
  • 列出薪金高于在部门30工作的所有员工的薪金的员工和薪金、部门名称。
select ename,sal,dname from emp join dept on emp.deptno=dept.deptno where sal>(select max(sal) from emp where deptno=30);
  • 列出每个部门工作的部门名称、员工的数量、平均工资和平均服务期限。
select deptno,count(empno),avg(sal),avg(SYSDATE()-hiredate) hiretime from emp group by deptno;
  • 列出所有部门的名称和部门人数。
select dname,table1.ce from (select deptno,count(empno) ce from emp group by deptno)table1 left join dept on table1.deptno=dept.deptno;
  • 列出各种工作的名称,最低工资及从事此工作的雇员姓名。
    先列举出一种错误做法
select empno,sal,job from emp order by job;
+-------+---------+-----------+
| empno | sal     | job       |
+-------+---------+-----------+
|  7788 | 3000.00 | ANALYST   |
|  7902 | 3000.00 | ANALYST   |
|  7369 |  800.00 | CLERK     |
|  7876 | 1100.00 | CLERK     |
|  7900 |  950.00 | CLERK     |
|  7934 | 1300.00 | CLERK     |
|  7566 | 2975.00 | MANAGER   |
|  7698 | 2850.00 | MANAGER   |
|  7782 | 2450.00 | MANAGER   |
|  7839 | 5000.00 | PRESIDENT |
|  7499 | 1600.00 | SALESMAN  |
|  7521 | 1250.00 | SALESMAN  |
|  7654 | 1250.00 | SALESMAN  |
|  7844 | 1500.00 | SALESMAN  |
+-------+---------+-----------+
select empno,min(sal),job from emp group by job;
+-------+----------+-----------+
| empno | min(sal) | job       |
+-------+----------+-----------+
|  7788 |  3000.00 | ANALYST   |
|  7369 |   800.00 | CLERK     |
|  7566 |  2450.00 | MANAGER   |
|  7839 |  5000.00 | PRESIDENT |
|  7499 |  1250.00 | SALESMAN  |
+-------+----------+-----------+
select emp.empno,sal from (select empno,min(sal) from emp group by job)table1 join emp on table1.empno=emp.empno;
+-------+---------+
| empno | sal     |
+-------+---------+
|  7788 | 3000.00 |
|  7369 |  800.00 |
|  7566 | 2975.00 |
|  7839 | 5000.00 |
|  7499 | 1600.00 |
+-------+---------+

下面是正确的做法

SELECT ename,sal,job from emp where (sal ,job) in(select min(sal),job from emp GROUP BY job);
+--------+---------+-----------+
| ename  | sal     | job       |
+--------+---------+-----------+
| SMITH  |  800.00 | CLERK     |
| WARD   | 1250.00 | SALESMAN  |
| MARTIN | 1250.00 | SALESMAN  |
| CLARK  | 2450.00 | MANAGER   |
| SCOTT  | 3000.00 | ANALYST   |
| KING   | 5000.00 | PRESIDENT |
| FORD   | 3000.00 | ANALYST   |
+--------+---------+-----------+
  • 列出各个部门的MANAGER(经理)的最低薪金及其名字,工作,部门编号
select ename,sal,job,deptno from emp where (job,sal) in (select job,min(sal) from emp where job='MANAGER' GROUP BY deptno );
  • 列出平均薪资最高的部门及其薪资
    错误做法
select deptno,avg(sal) avs from emp group by deptno
having  avs= (select max(table1.avgsal) from (select avg(sal) avgsal from emp group by deptno)table1);
Empty set (0.00 sec)

正确做法1

select deptno,avg(sal) avs from emp group by deptno 
having  ABS(avs- (select max(table1.avgsal) from (select avg(sal) avgsal from emp group by deptno)table1))<0.001;

正确做法2

select deptno,avg(sal) avs from emp group by deptno limit 1;
  • 列出所有员工的年工资,按年薪从低到高排序
select sal*12 ,ename from emp group by sal;
  • 查出某个员工的上级主管,并要求出这些主管中的薪水超过3000
select emp1.ename,emp2.ename from emp emp1 join emp emp2 on emp1.mgr=emp2.empno and emp2.sal>3000;

你可能感兴趣的:(SQL语句练习)