MySQL练习题集,及标准答案,牛客网笔试题,经典题型

 MySQL练习题集,及标准答案,牛客网笔试题,经典题型_第1张图片

MySQL练习题集,及标准答案,牛客网笔试题,经典题型_第2张图片

建表数据如下:

drop table if exists  film ;
drop table if exists  category  ; 
drop table if exists  film_category  ; 
CREATE TABLE IF NOT EXISTS film (
  film_id smallint(5)  NOT NULL DEFAULT '0',
  title varchar(255) NOT NULL,
  description text,
  PRIMARY KEY (film_id)
);
CREATE TABLE category  (
  category_id  tinyint(3)  NOT NULL ,
  name  varchar(25) NOT NULL, `last_update` timestamp,
  PRIMARY KEY ( category_id )
);
CREATE TABLE film_category  (
  film_id  smallint(5)  NOT NULL,
  category_id  tinyint(3)  NOT NULL, 
  `last_update` timestamp
);
INSERT INTO film VALUES(1,'ACADEMY DINOSAUR','A Epic Drama of a Feminist And a Mad Scientist who must Battle a Teacher in The Canadian Rockies');
INSERT INTO film VALUES(2,'ACE GOLDFINGER','A Astounding Epistle of a Database Administrator And a Explorer who must Find a Car in Ancient China');
INSERT INTO film VALUES(3,'ADAPTATION HOLES','A Astounding Reflection of a Lumberjack And a Car who must Sink a Lumberjack in A Baloon Factory');
INSERT INTO film VALUES(4,'AFFAIR PREJUDICE','A Fanciful Documentary of a Frisbee And a Lumberjack who must Chase a Monkey in A Shark Tank');
INSERT INTO film VALUES(5,'AFRICAN EGG','A Fast-Paced Documentary of a Pastry Chef And a Dentist who must Pursue a Forensic Psychologist in The Gulf of Mexico');
INSERT INTO film VALUES(6,'AGENT TRUMAN','A Intrepid Panorama of a robot And a Boy who must Escape a Sumo Wrestler in Ancient China');
INSERT INTO film VALUES(7,'AIRPLANE SIERRA','A Touching Saga of a Hunter And a Butler who must Discover a Butler in A Jet Boat');
INSERT INTO film VALUES(8,'AIRPORT POLLOCK','A Epic Tale of a Moose And a Girl who must Confront a Monkey in Ancient India');
INSERT INTO film VALUES(9,'ALABAMA DEVIL','A Thoughtful Panorama of a Database Administrator And a Mad Scientist who must Outgun a Mad Scientist in A Jet Boat');
INSERT INTO film VALUES(10,'ALADDIN CALENDAR','A Action-Packed Tale of a Man And a Lumberjack who must Reach a Feminist in Ancient China');

INSERT INTO category VALUES(1,'Action','2006-02-14 20:46:27');
INSERT INTO category VALUES(2,'Animation','2006-02-14 20:46:27');
INSERT INTO category VALUES(3,'Children','2006-02-14 20:46:27');
INSERT INTO category VALUES(4,'Classics','2006-02-14 20:46:27');
INSERT INTO category VALUES(5,'Comedy','2006-02-14 20:46:27');
INSERT INTO category VALUES(6,'Documentary','2006-02-14 20:46:27');
INSERT INTO category VALUES(7,'Drama','2006-02-14 20:46:27');
INSERT INTO category VALUES(8,'Family','2006-02-14 20:46:27');
INSERT INTO category VALUES(9,'Foreign','2006-02-14 20:46:27');
INSERT INTO category VALUES(10,'Games','2006-02-14 20:46:27');
INSERT INTO category VALUES(11,'Horror','2006-02-14 20:46:27');
INSERT INTO category VALUES(12,'Music','2006-02-14 20:46:27');
INSERT INTO category VALUES(13,'New','2006-02-14 20:46:27');
INSERT INTO category VALUES(14,'Sci-Fi','2006-02-14 20:46:27');
INSERT INTO category VALUES(15,'Sports','2006-02-14 20:46:27');
INSERT INTO category VALUES(16,'Travel','2006-02-14 20:46:27');

INSERT INTO film_category VALUES(1,6,'2006-02-14 21:07:09');
INSERT INTO film_category VALUES(2,11,'2006-02-14 21:07:09');
INSERT INTO film_category VALUES(3,6,'2006-02-14 21:07:09');
INSERT INTO film_category VALUES(4,11,'2006-02-14 21:07:09');
INSERT INTO film_category VALUES(5,6,'2006-02-14 21:07:09');
INSERT INTO film_category VALUES(6,6,'2006-02-14 21:07:09');
INSERT INTO film_category VALUES(7,5,'2006-02-14 21:07:09');
INSERT INTO film_category VALUES(8,6,'2006-02-14 21:07:09');
INSERT INTO film_category VALUES(9,11,'2006-02-14 21:07:09');
INSERT INTO film_category VALUES(10,15,'2006-02-14 21:07:09');

问题:

查找描述信息(film.description)中包含robot的电影对应的分类名称
(category.name)以及电影数目,而且还需要该分类包含电影总数量>=5部 。

答案如下:

 -- 方法一
 select b.name,count(a.film_id) from
(
  select f.film_id,fc.category_id from film f join film_category fc
  on f.film_id = fc.film_id
  where f.description like '%robot%'
) a
join
(
  select fc.category_id,ca.name,count(fc.film_id) num from film_category fc 
  join category ca
  on fc.category_id = ca.category_id
  group by ca.category_id
  having num>=5
) b
on a.category_id=b.category_id 
where b.num>=5;

-- 方法二
 WITH t1 AS
(
    SELECT
        fc.category_id,
        count(fc.category_id) AS number
    FROM film_category fc
    GROUP BY fc.category_id
    HAVING number >= 5
),
t2 AS
(
    SELECT
        c.category_id,
        c.name,
        f.film_id
    FROM film_category fc
    JOIN film f USING(film_id)
    JOIN category c USING(category_id)
    WHERE f.description LIKE '%robot%'
)
 
SELECT
    t2.name,
    COUNT(t2.film_id)
FROM t1
JOIN t2
    ON t1.category_id = t2.category_id;

-- 方法三
select * from (select name, category_id from category 
where category_id in (
	select distinct category_id from film_category 
	where film_id in (
	select film_id from film where description like '%robot%')
)) t1, (select category_id, count(*) num from film_category 
group by category_id
having num >= 5) t2 where t1.category_id = t2.category_id;

方法三详解:

-- 包含robot的film.id
select film_id from film where description like '%robot%';

-- 查category_id
select distinct category_id from film_category
where film_id in (
select film_id from film where description like '%robot%');

-- 查分类名称
select name, category_id from category
where category_id in (
select distinct category_id from film_category
where film_id in (
select film_id from film where description like '%robot%')
);

-- 查电影数目 >= 5的分类id 和 数量
select category_id, count(*) num from film_category
group by category_id
having num >= 5;

Oracle经典建表数据:

create table dept(
	deptno int,
    dname varchar(20),
    loc varchar(20)
);
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'); 

create table emp(
	empno int,
    ename varchar(20),
    job varchar(20),
    mgr int,
    hiredate date,
    sal double,
    comn double,
    deptno int
);

INSERT INTO `emp` VALUES (7369, 'SMITH', 'CLERK', 7902, '1980-12-17', 800, NULL, 20);
INSERT INTO `emp` VALUES (7499, 'ALLEN', 'SALESMAN', 7698, '1981-02-20', 1600, 300, 30);
INSERT INTO `emp` VALUES (7521, 'WARD', 'SALESMAN', 7698, '1981-02-22', 1250, 500, 30);
INSERT INTO `emp` VALUES (7566, 'JONES', 'MANAGER', 7839, '1981-04-02', 2975, NULL, 20);
INSERT INTO `emp` VALUES (7654, 'MARTIN', 'SALESMAN', 7698, '1981-08-28', 1250, 1400,30);
INSERT INTO `emp` VALUES (7698, 'BLAKE', 'MANAGER', 7839, '1981-05-01', 2850, NULL, 30);
INSERT INTO `emp` VALUES (7782, 'CLAKE', 'MANAGER', 7839, '1981-06-09', 2450, NULL, 10);
INSERT INTO `emp` VALUES (7788, 'SCOTT', 'ANALYST', 7566, '1987-04-19', 3000, NULL, 20);
INSERT INTO `emp` VALUES (7839, 'KING', 'PRESIDENT', NULL, '1981-11-17', 5000, NULL, 10);
INSERT INTO `emp` VALUES (7844, 'TURNER', 'SALESMAN', 7698, '1981-09-08', 1500, 0, 30);
INSERT INTO `emp` VALUES (7876, 'ADAMS', 'CLERK', 7788, '1987-05-23', 1100, NULL, 20);
INSERT INTO `emp` VALUES (7900, 'JAMES', 'CLERK', 7698, '1981-12-03', 950, NULL, 30);
INSERT INTO `emp` VALUES (7902, 'FORD', 'ANALYST', 7566, '1981-12-03', 3000, NULL, 20);
INSERT INTO `emp` VALUES (7934, 'MILLER', 'CLERK', 7782, '1982-01-23', 1300, NULL, 10);

 问题及答案:

(初级)

-- 1. 查询职员表中工资大于 1600 的员工姓名和工资
select ename, sal from emp where sal > 1600;
-- 2. 查询职员表中员工号为 7369 的员工的姓名和部门号码
select ename, deptno from emp where empno = 7369;
-- 3. 选择职员表中工资不在 2000 到 3000 的员工的姓名和工资
select ename, sal from emp where sal not between 2000 and 3000;
-- 4. 选择职员表中在 20 和 30 号部门工作的员工姓名和部门号
select ename, deptno from emp where deptno in (20, 30);
-- 5. 选择职员表中没有管理者的员工姓名及职位
select ename, job from emp where mgr is null;
-- 6. 选择职员表中有奖金的员工姓名,工资和奖金,按工资倒序排列
select ename, sal, comm from emp where comm is not null;
select ename, sal, comm from emp where comm > 0;
-- 7. 选择职员表中员工职位的第二个字母是 a 的员工姓名
select ename,job from emp where job like '_a%';
-- 8. 查询那些尚未分配部门的员工的姓名
select ename from emp where deptno is null;
-- 9. 列出部门表中的部门名字和所在城市;
select dname, loc from dept;
-- 10. 显示出职员表中的不重复的职位;
select distinct job from emp;
-- 11. 连接职员表中的职员名字、职位、薪水,列之间用逗号连接,列头显示成 OUT_PUT
select concat(ename,',',job,',',sal) as OUT_PUT from emp;
-- 12. 查询职员表 emp 中员工号、姓名、工资,以及工资提高百分之 20%后的结果,元为单位进行四舍五入
select empno,ename,sal,round(sal*1.2) from emp;
-- 13. 查询员工的姓名和工资数,条件限定为工资数必须大于 3200,并对查询结果按入职时间进行排序,早入职排在前面,晚入职排在后面。
select ename, sal, hiredate from emp where sal > 1200
order by hiredate asc;
-- 14. 列出部门表中除了 ACCOUNTING 部门还有哪些部门。
-- 不等于  !=  <>
select dname from dept where dname <> 'ACCOUNTING';
-- 15. 已知员工的收入为:薪资+绩效*0.8,如果绩效为null,则表示绩效为0。查询员工的姓名以及月收入(列名为money),并按照月收入升序排序
select ename, sal+ifNull(comm,0)*0.8 as money from emp;
-- 16. 将员工的姓名按首字母排序,并列出姓名的长度(length)
select ename, length(ename) from emp order by ename;
-- 17. 查询各员工的姓名 ename,并显示出各员工在公司工作的月份数 (即:和当前日期比较,该员工已经工作了几个月,  用整数表示)。
select ename, timestampdiff(month, hiredate, now()) from emp;
-- 18. 现有数据表 Customer,其结构如下所示:
--        cust_id int(4)   Primary Key,    --客户编码
--        cname VARCHAR(25) Not Null,      --客户姓名
--        birthday DATE,                   --客户生日
--        account int.                     --客户账户余额 
--   1. 构造 SQL 语句,列出 Customer 数据表中每个客户的信息。如果客户生日未提供,则该列值显示“not available”  。如果没有余额信息,则显示“no account”。
select cust_id,cname,ifNull(birthday, 'not available'),ifNull(account, 'no account')  from Customer;
     2. 构造 SQL 语句,列出生日在 1987 年的客户的全部信息。
select * from Customer where year(birthday) = 1987;
--   3. 构造 SQL 语句,列出客户帐户的余额总数。

-- 19. 按照"2009年4月11日 20-35-10"格式显示系统时间。
select date_format(now(), '%Y年%m月%d日 %H-%i-%s') ;
-- 20. 构造 SQL 语句查询员工表 emp 中员工编码 empno,姓名 ename,以及月收入(薪水  +  奖金),
-- 参考15题
-- 21. 查找员工姓名的长度是 5 个字符的员工信息。
select * from emp where length(ename)=5;
-- 22. 查询员工的姓名和工资,按下面的形式显示:(提示:使用 lpad 函数)
select ename, lpad(sal, 15, '$')  salary from emp;
-- 23. 查询薪水大于 1600 元的员工的姓名和薪水,薪水值显示为"$5000.00"这种形式,并对查询结果按薪水的降序方式进行排列;
select ename, concat('$',format(sal, 2)) from emp where sal > 1600
order by sal desc;
-- 24. 构造查询语句,产生类似于下面形式的结果:
--    即hiredate列显示的格式为“1980-12-17”;再将hiredate列以“1980年12月17日”格式显示,并且显示的列名为“REVIEW”。
-- 参考第19题

select now();
select round(12.34);

-- 查询员工信息, 按照薪资排序 (升序, 降序)
-- null值也会参与排序, 无穷小
select sal s from emp e where e.sal > 1200 order by s asc; -- 默认升序
select * from emp order by sal desc; -- 降序

(中级) 

-- 2. 查询公司员工工资的最大值,最小值,平均值,总和
select max(sal),min(sal),avg(sal),sum(sal) from emp;
-- 3. 查询每个部门中各个职位的最高薪水。
select job,deptno,max(sal) from emp group by job, deptno order by deptno;
-- 4. 选择具有各个 job 的员工人数(提示:对 job 进行分组)
select job,count(1) from emp group by job;
-- 5. 查询员工最高工资和最低工资的差距,列名为 DIFFERENCE
select max(sal)-min(sal) as DIFFERENCE from emp;
-- 6. 查询各个管理者属下员工的最低工资,其中最低工资不能低于 2000,没有管理者的员工不计算在内
-- 查询出来的最低薪资低于2000, 就不显示了
select mgr, min(sal) from emp
 where mgr is not null
 group by mgr
 having min(sal) >= 2000;
 select mgr, min(sal) from emp group by mgr;
-- 7. 查询各个部门中工资大于1500的员工人数
select count(1), deptno from emp where sal > 1500 group by deptno;
-- 8. 查询各部门的平均绩效comm,如果绩效为null,则按数值0进行统计
select deptno,avg(ifnull(comm,0)) from emp group by deptno;
-- 11. 和第三题一样
select classid,subject,max(score) from student group by classid,subject;
-- 12. 列出职员表中所有薪水高于平均薪水值的员工信息 - 子查询
select avg(sal) from emp;
select ename,job,sal from emp where sal > 2073.2143;
-- 13. 每门课都大于80分的学生姓名 -> 最低分 大于 80分
select name from stu group by name having min(fenshu) > 80;

(进阶)

-- 1. 查询员工的姓名及其所在部门的名字和城市
select ename,dname,loc from emp e,dept d where e.deptno = d.deptno;
-- 2. 查询员工的姓名和他的管理者的姓名
select e.ename, d.ename from emp e left join emp d on e.mgr = d.empno;
-- 3. 查询员工的编号、姓名、部门编码、部门名称以及部门所在城市。要求:把没有部门的员工也查出来
select empno,ename,e.deptno,dname,loc 
from emp e left join dept d 
on e.deptno = d.deptno;
-- 4. 查询员工的信息及其所在部门的信息。要求:把没有员工的部门也查出来
select empno,ename,e.deptno,dname,loc 
from emp e right join dept d 
on e.deptno = d.deptno;
-- 5. 查询员工的信息及其所在部门的信息。要求:只查询有员工的部门,有部门的员工
select empno,ename,e.deptno,dname,loc 
from emp e join dept d 
on e.deptno = d.deptno;
-- 6. 查询并显示SALES部门的职位
select DISTINCT job from emp e, dept d where e.deptno = d.deptno and dname='SALES';
-- 7. 查询所有部门的名称、所在地、员工数量以及平均工资
select dname,loc,count(1),round(avg(sal),1 )
from dept d join emp e on d.deptno = e.deptno
group by dname,loc;
-- 9. 假设员工表中,员工和管理者中间只有一个层级,也就是说,每个员工最多只有一个上级,作为管理者的员工不再有上级管理者,并且,上级管理者相同的员工,他们属于同一个部门。
-- 找出EMP中那些工资高于他们所在部门的管理者工资的员工。
select e.ename from emp e join emp m on e.mgr = m.empno where e.sal > m.sal;
-- 10. 有USERLIST表如图所示:

 (进阶2)

-- 1. 查询哪个部门的平均工资是最高的,列出部门编码,平均工资。
-- 查各个部门的平均工资
select avg(sal) avg_sal, deptno from emp group by deptno;
-- 查平均薪资最高值
select max(avg_sal) max from 
(select avg(sal) avg_sal, deptno from emp group by deptno) e;
-- 最终结果
select deptno, avg(sal) from emp group by deptno
 having avg(sal) = (select max(avg_sal) max from 
(select avg(sal) avg_sal, deptno from emp group by deptno) e);

-- 通过排序, 取最大
select avg(sal) avg_sal, deptno from emp where deptno is not null
group by deptno
order by avg_sal desc limit 0, 1;

-- 2. 列出各个部门中工资最高的员工的信息:名字、部门号、工资。
-- 各部门工资最高是多少
select max(sal), deptno from emp group by deptno;

-- 最终查询
select ename, e.deptno, sal from emp e, 
(select max(sal) max_sal, deptno from emp group by deptno) m
where e.deptno = m.deptno and e.sal = m.max_sal;

-- 简化写法
select ename, e.deptno, sal from emp e
where (sal, deptno) in 
(select max(sal), deptno from emp group by deptno);

-- 3. 查询管理者是“KING”的员工姓名(ename)和工资(sal)。
-- King的员工号
select empno from emp where ename = 'KING';
-- 最终查询
select ename, sal from emp 
 where mgr = 
	( select empno from emp where ename = 'KING' );

-- 4. 查询部门所在地(loc)为“NEW YORK”的部门的员工姓名、部门名称和岗位名称。
-- 查 “NEW YORK” 的部门号
select deptno from dept where loc = 'NEW YORK';
-- 最终查询
select ename, dname, job from emp e, dept d 
where e.deptno = d.deptno and
e.deptno = (select deptno from dept where loc = 'NEW YORK');

-- 另一种写法, 子查询替代表连接的写法, 子查询在select子句中
select ename, job, 
 (select dname from dept d where d.deptno = e.deptno)
 from emp e 
 where e.deptno = 
	(select deptno from dept where loc = 'NEW YORK');

-- 5. 查询工资比公司平均工资高的所有员工的员工号,姓名和工资。
-- 查 公司平均工资
select avg(sal) from emp;

-- 最终查询
select empno, ename, sal from emp 
where sal > (select avg(sal) from emp);

-- 6. 查询姓名中包含字母“u”的员工在相同部门的员工的员工号和姓名。
-- 查名字包含u的员工的部门号
select deptno from emp where ename like '%u%';

-- 最终
select empno, ename from emp 
where deptno in (select deptno from emp where ename like '%u%');

-- 7. 查询哪些员工的薪水比本部门的平均薪水低。
-- 各部门平均薪资
select avg(sal) avg_sal, deptno from emp group by deptno;

-- 最终
select ename from emp e, 
	(select avg(sal) avg_sal, deptno from emp group by deptno) d
    where e.deptno = d.deptno and e.sal < d.avg_sal;

-- 8. SALES部门有哪些职位?
-- 查SALES部门编号
select deptno from dept where dname = 'SALES';
-- 最终
select distinct job from emp 
where deptno = (select deptno from dept where dname = 'SALES');

-- 9. 哪些人不是别人的经理?
-- 查是经理的人的编号
select distinct mgr from emp where mgr is not null;
-- 最终
select * from emp where empno not in 
  (select distinct mgr from emp where mgr is not null);

-- 10. 谁的薪水比FORD高?如果有多个同名,比任何一个叫FORD的人高就行
-- 查FORD的薪水
select sal from emp where ename = 'FORD';
-- 最终
select * from emp where sal > any
	(select sal from emp where ename = 'FORD');
-- 11. 谁和FORD同部门?列出除了FORD之外的员工名字
-- 查FORD部门号
select deptno from emp where ename = 'FORD';
-- 最终
select ename from emp 
 where deptno in (select deptno from emp where ename = 'FORD')
 and ename <> 'FORD';

-- 12. 哪个部门的人数比部门20的人数多
-- 查部门20的人数
select count(1) from emp where deptno = 20;
-- 最终
select deptno, count(1) from emp group by deptno
having count(1) > (select count(1) from emp where deptno = 20);

-- 13. 列出员工名字和职位,查询员工所在的部门平均薪水大于2000元的员工信息
-- 查平均薪资大于2000的部门
select deptno from emp group by deptno having avg(sal) > 2000;
-- 最终
select ename, job from emp
where deptno in (select deptno from emp group by deptno having avg(sal) > 2000);

-- 16. 找出EMP中那些工资高于他们所在部门普通员工(不包含管理者)平均工资的员工。
select a.ename, a.sal, a.deptno, b.maxsal
from emp a,
(select deptno, avg(sal) avgsal
from emp
group by mgr) b
where a.deptno = b.deptno
and a.sal > b.maxsal;

你可能感兴趣的:(MySQL,mysql,数据库,java)