MySql练习题(60道)
建表
CREATE DATABASE Company
USE Company
CREATE TABLE department(dept_no VARCHAR(3),
dept_name VARCHAR(15),
location VARCHAR(7),
memo VARCHAR(4)
);
INSERT INTO department VALUES("d1","Research","Dallas","达拉斯");
INSERT INTO department VALUES("d2","Accounting","Seattle","西雅图");
INSERT INTO department VALUES("d3","Marketing","Dallas","达拉斯");
CREATE TABLE employee(emp_no INT,
emp_fname VARCHAR(8),
emp_lname VARCHAR(10),
dept_no VARCHAR(2)
);
INSERT INTO employee VALUES(25348,"Matthew","Smith","d3");
INSERT INTO employee VALUES(10102,"Ann","Jones","d3");
INSERT INTO employee VALUES(18316,"John","Barrimore","d1");
INSERT INTO employee VALUES(29346,"James","James","d2");
INSERT INTO employee VALUES(9031,"Elisa","Brrtoni","d2");
INSERT INTO employee VALUES(2581,"Elke","Hansel","d2");
INSERT INTO employee VALUES(28559,"Sybill","Moser","d1");
CREATE TABLE project(project_no VARCHAR(2),
project_name VARCHAR(10),
budget INT(6)
);
INSERT INTO project VALUES("p1","Apollo",120000);
INSERT INTO project VALUES("p2","Gemini",95000);
INSERT INTO project VALUES("p3","Mercury",185600);
SELECT * FROM project
CREATE TABLE works_on(emp_no INT(5),
project_no VARCHAR(2),
job VARCHAR(10),
enter_date DATETIME
);
INSERT INTO works_on VALUES(10105,"p1","Analyst","1997.10.1");
INSERT INTO works_on VALUES(10102,"p3","Manager","1991-1-1");
INSERT INTO works_on VALUES(25348,"p2","Clerk","1998-2-15");
INSERT INTO works_on VALUES(18316,"p2",NULL,"1998-6-1");
INSERT INTO works_on VALUES(29346,"p2",NULL,"1997-12-15");
INSERT INTO works_on VALUES(2581,"p3","Analyst","1998-10-15");
INSERT INTO works_on VALUES(9031,"p1","Manager","1998-4-15");
INSERT INTO works_on VALUES(28559,"p2","Clerk","1999-2-1");
INSERT INTO works_on VALUES(9031,"p3","Clerk","1997-11-15");
INSERT INTO works_on VALUES(29346,"p1","Clerk","1998-1-4");
CREATE TABLE employee_enh(emp_no INT(5),
emp_fname VARCHAR(10),
emp_lname VARCHAR(10),
dept_no VARCHAR(2),
domicile VARCHAR(15)
);
INSERT INTO employee_enh VALUES(25348,"Matthew","Smith","d3","San Antonio");
INSERT INTO employee_enh VALUES(10102,"Ann","Jones","d3","Houston");
INSERT INTO employee_enh VALUES(18316,"John","Barrimore","d1","San Antonio");
INSERT INTO employee_enh VALUES(29346,"James","James","d2","Seattle");
INSERT INTO employee_enh VALUES(9031,"Elisa","Bertoli","d2","Portland");
INSERT INTO employee_enh VALUES(2581,"Elke","Kim","d2","Tacoma");
INSERT INTO employee_enh VALUES(28559,"Sybill","Moser","d1","Houston");
问题解析
-- 1 获取表work_on中所有的行
SELECT * FROM works_on;
-- 2 获取售货员(Clerk)的职员编号
SELECT emp_no,job FROM works_on WHERE job='Clerk';
-- 3 获取为项目2工作,且编号小于10000的所有职员的编号
SELECT emp_no FROM works_on WHERE project_no='p2' AND emp_no<10000;
-- 4 获取不是1998年参加项目的所有的职员的编号
SELECT emp_no,enter_date FROM works_on WHERE enter_date NOT LIKE '1998%' -- %(匹配多个任意字符) like(模糊查询)
-- 5 获取在项目1中担任领导工作(指分析员Analyst和经理Manager) 的所有职员的编号
SELECT emp_no, project_no, job FROM works_on WHERE project_no = 'p1' AND job IN('Analyst','Manager');
-- 6 获取项目2中所有工种尚未被决定的职员的加入日期
SELECT * FROM works_on WHERE project_no = 'p2' AND job IS NULL;
-- 7 获取名first name中含有两个t的职员的编号和姓last name
SELECT emp_no, emp_fname, emp_lname FROM employee WHERE emp_fname LIKE '%t%t%';
-- 8 获取姓last name中的第二个字母是o或a,且结束字母是es的所有职员编号和名first name
SELECT emp_no, emp_fname, emp_lname FROM employee WHERE emp_lname LIKE '_o%es' OR '_a%es'; -- -(匹配单个任意字符)
-- 9 找出所有部门位于Seattle的所有职员的编号
SELECT emp_no, domicile FROM employee_enh WHERE domicile = 'Seattle';
-- 10 获取在04.01.1998参加项目的所有职员的姓名
SELECT emp_no, enter_date FROM works_on WHERE enter_date LIKE '1998-01-04%';
-- 11 使用座落地点对所有的部门进行分组
SELECT memo FROM department GROUP BY memo; -- group by(分组查询)
-- 12 子句distinct和group by之间的区别是什么?
-- distinct是对结果进行去重复,group by是对数据进行分组 语法:SELECT DISTINCT 列名称 FROM 表名称
-- 13 子句group by对NULL值是如何进行处理的?是否与处理NULL值的通用方法一 致?
-- 所有的null值为一组
-- 14 COUNT(*)和COUNT(column)之间的区别何在?
SELECT COUNT(*) FROM works_on;
SELECT COUNT(job) FROM works_on;
-- 前者是统计总数,后者是统计值不为null的总数,如果后者要统计所有的,必须传入没有null的字段
-- 15 找出最大职员编号
SELECT MAX(emp_no) FROM works_on;
-- 16 找出从事人数多于两个的工种
SELECT job FROM works_on WHERE job IS NOT NULL GROUP BY job HAVING COUNT(*) > 2;
-- * where:在分组之前对条件进行限定。不满足条件,就不会参与分组 * having:在分组之后,对结果集的筛选
-- 17 找出是售货员或者是工作于部门d3的所有职员的编号(左外连接)
SELECT works_on.emp_no, works_on.job ,employee_enh.dept_no FROM works_on LEFT JOIN employee_enh ON works_on.emp_no = employee_enh.emp_no WHERE job = 'Clerk' OR dept_no = 'd3';
-- 18 如果想在一个查询中连接多个表(假设是N个),共需要几个连接条件?
-- N-1
-- 19 获取为项目Gemini工作的所有职员的编号和所从事的工种(左外连接)
SELECT works_on.`emp_no`,works_on.`job`,project.`project_name` FROM works_on LEFT JOIN project ON works_on.project_no = project.project_no WHERE project_name = 'Gemini';
-- 20 获取为研究Research部门或会计Account部门工作的所有职员的姓名(左外连接)
SELECT employee.emp_fname, employee.emp_lname, department.dept_name FROM employee LEFT JOIN department ON employee.dept_no = department.dept_no WHERE department.dept_name IN('Research', 'Accounting');
-- 21 获取属于部门d1的所有售货员的加入日期
SELECT works_on.emp_no,works_on.enter_date FROM works_on LEFT JOIN employee ON works_on.emp_no=employee.emp_no WHERE employee.dept_no='d1' AND works_on.job = 'Clerk';
-- 22 获取有两个或多个售货员为之工作的项目名称
SELECT project.`project_name` FROM project LEFT JOIN works_on ON project.`project_no`=works_on.`project_no` GROUP BY project.`project_name` HAVING COUNT(*)>=2;
-- 23 获取所有身为经理且为Mercury工作的职员的姓名(连环左外连接)
SELECT employee_enh.`emp_fname`,employee_enh.`emp_lname`,works_on.job,project.`project_name` FROM employee_enh LEFT JOIN works_on ON employee_enh.`emp_no`=works_on.`emp_no` LEFT JOIN project ON works_on.`project_no`=project.`project_no` WHERE works_on.job = 'Manager' AND project.project_name = 'Mercury';
-- 24 对于参于项目的日期与至少一名其他职员相同的所有职员,获取其姓名
SELECT employee_enh.emp_fname, employee_enh.emp_lname, works_on.enter_date FROM employee_enh LEFT JOIN works_on ON employee_enh.emp_no = works_on.emp_no GROUP BY works_on.enter_date HAVING COUNT(*) > 1;
-- 25 获取属于市场(Marketing)部的所有职员的编号
SELECT employee.emp_no, department.dept_name FROM employee LEFT JOIN department ON employee.dept_no = department.dept_no WHERE department.dept_name = 'Marketing';
-- 26 插入编号为11111,名字为Julia Long的新职员的数据。她所在的部门编号尚未知。
INSERT INTO works_on(emp_no,enter_date) VALUES(11111,'2019-3-29');
INSERT INTO employee(emp_no,emp_fname,emp_lname) VALUES(11111,'Julia','Long');
INSERT INTO employee_enh(emp_no,emp_fname,emp_lname,domicile) VALUES (1111,'Julia','Long','Xian');
-- 27 创建一个名为emp_d1_d2的新表,表中包含所有为部门d1或d2工作的职员,并且从表employee中调入相应的行。
-- 语法:create table 表名 as select 要复制的内容 from 要复制的表;
CREATE TABLE emp_d1_d2 AS SELECT *FROM employee WHERE dept_no IN('d1','d2')
-- 28 创建一个新表,表中包含所有参加项目的时间为1998年的职员,并从表employee中调入相应的行
CREATE TABLE emp_date_1998 AS SELECT employee.* FROM employee LEFT JOIN works_on ON employee.`emp_no`=works_on.`emp_no` WHERE enter_date LIKE '1998%';
-- 29 修改为项目p1工作,且职称是经理的所职员的工种。从现在开始,他们必须从事售货员的工作。
-- 语法:update 表名 set 字段名 = 值;
UPDATE works_on SET job='Clerk' WHERE project_no='p1' AND job='Manager';
-- 30 所有项目的预算不再是确定的。对于所有的预算赋NULL值
UPDATE project SET budget=NULL;
-- 31 修改编号为28559的职员的工种。从现在开始,他们将成为她所在项目的项目经理
UPDATE works_on SET job='Manager' WHERE emp_no=28559;
-- 32 对于经理的职员编号为10102的项目,增加其预算,增加额度为10%
UPDATE project SET budget=(budget * 1.1) WHERE project_no=(SELECT project_no FROM works_on WHERE job='Manager' AND emp_no=10102);
-- 33 对于职员James所在的那个部门,改变其名称,新的部门名称为Sales
UPDATE department SET dept_name='Sales' WHERE dept_no=(SELECT dept_no FROM employee WHERE emp_fname='James');
-- 34 对于为项目p1工作并且是属于销售Sales部门的所有员工,改变其加入项目的日期。新的日期为12.12.1998
UPDATE works_on SET enter_date = '1998-12-12 00:00:00' WHERE emp_no IN(SELECT a.emp_no FROM(SELECT works_on.`emp_no`FROM works_on) AS a LEFT JOIN employee ON a.emp_no=employee.`emp_no` LEFT JOIN department ON employee.`dept_no`=department.`dept_no`) AND project_no='p1';
-- 35 删除坐落于Seattle的所有部门
-- 先将员工的部门编号改为NULL
UPDATE employee SET dept_no=NULL WHERE dept_no=(SELECT dept_no FROM department WHERE location='Seattle');
-- 再删除部门
DELETE FROM department WHERE location='Seattle';
-- 36 目p3已经完成了。删除样例数据库中与这个项目有关的所有信息
-- 先将员工的项目编号改为null
UPDATE works_on SET project_no=NULL WHERE project_no='p3';
-- 再删除项目
DELETE FROM project WHERE project_no='p3';
-- 37 删除表works_on中为座落于Dallas的部门工作的所有职员的信息
DELETE FROM works_on WHERE emp_no IN(SELECT employee.`emp_no` FROM employee LEFT JOIN department ON employee.`dept_no`=department.`dept_no` WHERE department.`location`='Dallas');
-- 38 获取为项目p2工作的所有售货员的职员编号、项目编号和参加项目的日期,并将选取出来的数据加载到一个新表中(clerk_t)
CREATE TABLE dallas_dept AS SELECT dept_no, dept_name FROM department;
-- 39 获取为项目p2工作的所有售货员的职员编号、项目编号和参加项目的日期,并将选取出来的数据加载到一个新表中(clerk_t)
CREATE TABLE clerk_t AS SELECT emp_no, project_no, enter_date FROM works_on WHERE project_no = 'p2' AND job = 'Clerk';
-- 40 将为项目p2工作且编号为18316的职员的工作任务设置为Manager
UPDATE works_on SET job = 'Manager' WHERE project_no = 'p2' AND emp_no = 18316;
-- 41 因为Jones女士生病了,故将其在所有项目中担任的职位都置为NULL
UPDATE works_on SET job = NULL WHERE emp_no IN(SELECT temp.emp_no FROM (SELECT works_on.emp_no FROM works_on) AS temp LEFT JOIN employee ON temp.emp_no = employee.emp_no WHERE employee.emp_lname = 'Jones');
-- 42 Moser女士将要离开,删除数据库中与她相关的所有行
DELETE FROM works_on WHERE emp_no IN (SELECT emp_no FROM employee WHERE emp_lname='Moser');
DELETE FROM employee WHERE employee.`emp_lname`='Moser';
DELETE FROM employee_enh WHERE employee_enh.`emp_lname`='Moser';
-- 43 获取参与项目的日期与表中最早的日期相等的所有职员的编号和参与日期
SELECT emp_no,enter_date FROM works_on WHERE enter_date =(SELECT MIN(enter_date) FROM works_on);
-- 44 获取在1998年10月15日加入项目的所有职员的编号,姓名和工种
SELECT works_on.emp_no, employee.emp_fname, employee.emp_lname, works_on.job FROM works_on LEFT JOIN employee ON works_on.emp_no = employee.emp_no WHERE works_on.enter_date LIKE '1998-10-15%';
-- 45 获取编号最小的那位职员所从事的工作
SELECT emp_no, job FROM works_on WHERE emp_no IN(SELECT MIN(emp_no) FROM works_on);
-- 46 获取是职员地居住地,但不是任何一个部门所在地的所有城市
SELECT DISTINCT employee_enh.domicile FROM employee_enh LEFT JOIN department ON employee_enh.dept_no = department.dept_no WHERE employee_enh.domicile != department.location; -- 关键词 DISTINCT 用于返回唯一不同的值
-- 47 获取是职员地居住地,但不是任何一个部门所在地的所有城市
SELECT DISTINCT employee_enh.domicile FROM employee_enh LEFT JOIN department ON employee_enh.dept_no = department.dept_no WHERE employee_enh.domicile != department.location;
-- 48 获取工作部门不在Seattle的所有职员的姓名
SELECT employee.emp_fname, employee.emp_lname FROM employee LEFT JOIN department ON employee.dept_no = department.dept_no WHERE department.location != 'Seattle';
-- 49 获取位于同一城市的所有部门的详细信息
SELECT * FROM department WHERE location IN(SELECT location FROM department GROUP BY location HAVING COUNT(*)>1);
-- 50 对于作为职员居住地的所有城市,或者既是居住地又是工作地点的所有城市,返回相应的所有职员详细信息及其工作部门的所在地
SELECT works_on.*, employee_enh.emp_fname, employee_enh.emp_lname, employee_enh.domicile, department.* FROM works_on LEFT JOIN employee_enh ON works_on.emp_no = employee_enh.emp_no LEFT JOIN department ON employee_enh.dept_no = department.dept_no;
-- 51 获取为项目Gemini工作地所有职员的全部详细信息
SELECT employee_enh.*, works_on.project_no, works_on.job, works_on.enter_date FROM employee_enh LEFT JOIN works_on ON employee_enh.emp_no = works_on.emp_no LEFT JOIN project ON works_on.project_no = project.project_no WHERE project.project_name = 'Gemini';
-- 52 对于居住地在字母排序上早于部门地址的所有职员,获取其职员信息与部门信息的所有组合
SELECT works_on.emp_no, works_on.job, works_on.enter_date, employee_enh.emp_fname, employee_enh.emp_lname, employee_enh.domicile, department.dept_name, department.location, department.memo, project.project_name FROM department LEFT JOIN employee_enh ON department.dept_no = employee_enh.dept_no LEFT JOIN works_on ON employee_enh.emp_no = works_on.emp_no LEFT JOIN project ON works_on.project_no = project.project_no WHERE employee_enh.domicile < department.location;
-- 53 获取会计部门中的职员所工作的项目名称(冗余重复要删除)
SELECT DISTINCT project_name FROM project LEFT JOIN works_on ON project.project_no = works_on.project_no LEFT JOIN employee ON works_on.emp_no = employee.emp_no LEFT JOIN department ON employee.dept_no = department.dept_no WHERE department.dept_name = 'Accounting';
-- 54 获取与至少一位其他员工工作在同一部门且居住在同一城市的每一名职员的编号、姓名和居住地。(提示:要使用到表employee_enh)
SELECT emp_no, emp_fname, emp_lname, dept_no, domicile FROM employee_enh WHERE CONCAT(dept_no, '(', domicile, ')') IN(SELECT CONCAT(dept_no, '(', domicile, ')') AS address FROM employee_enh GROUP BY address HAVING COUNT(*) > 1); -- CONCAT函数用于将两个字符串连接起来,形成一个单一的字符串。
-- 55 创建一个包含所有为部门d1工作的雇员的数据的视图
CREATE VIEW viewD1 AS SELECT * FROM employee_enh WHERE dept_no = 'd1';
SELECT * FROM viewD1;
-- 56 在表project中,创建一个可以被允许浏览表中所有数据(除列budgetc 以外)的雇员所使用的视图
CREATE VIEW viewPro1 AS SELECT project_no, project_name FROM project;
SELECT * FROM viewPro1;
-- 57 创建一个视图,视图中包括所有在1998年下半年进入他们工作项目的雇员的姓名
CREATE VIEW view57 AS SELECT works_on.emp_no, works_on.project_no,employee.emp_fname AS '名',employee.emp_lname AS '姓', works_on.enter_date FROM works_on, employee WHERE works_on.emp_no = employee.emp_no AND works_on.enter_date >= '1998-07-01';
-- 查看视图
SELECT * FROM view57;
-- 删除视图
DROP VIEW view57;
-- 58 解决前面的几个练习以使最初的列f_name和l_name能在视图中分别有新的名称:first和last
-- 找到了改变表字段的方法,视图目前采用重新定义的方法
ALTER TABLE department CHANGE dept_name NAME VARCHAR(20);
ALTER TABLE department CHANGE NAME dept_name VARCHAR(20);
DROP VIEW viewD1;
CREATE VIEW viewD1 AS SELECT emp_no,employee_enh.`emp_fname` AS FIRST,employee_enh.`emp_lname` AS LAST,dept_no,domicile FROM employee_enh WHERE dept_no = 'd1';
SELECT * FROM viewd1;
-- 59 使用视图,显示出所有姓是以字母M开头的雇员的详细资料
-- 先创建相应视图
CREATE VIEW view_fname_m AS SELECT works_on.emp_no AS '职员编号', employee_enh.emp_fname, employee_enh.emp_lname AS '姓', works_on.job AS '岗位', project.project_name AS '项目', project.budget '项目预算', works_on.enter_date '加入日期', department.dept_name AS '部门', employee_enh.domicile AS '居住地' FROM works_on, employee_enh, project, department WHERE department.dept_no = employee_enh.dept_no AND employee_enh.emp_no = works_on.emp_no AND works_on.project_no = project.project_no;
SELECT * FROM view_fname_m;
-- 再进行条件显示
SELECT * FROM view_fname_m WHERE emp_fname LIKE 'm%';
-- 60 创建一个视图,包括所有的名叫Smith的雇员所参与工作项目的详细资料
CREATE VIEW view60 AS SELECT works_on.emp_no AS '职员编号', employee_enh.emp_fname AS '名', employee_enh.emp_lname AS '姓', works_on.job AS '岗位', project.project_name AS '项目', project.budget '项目预算', works_on.enter_date '加入日期', department.dept_name AS '部门', employee_enh.domicile AS '居住地' FROM works_on, employee_enh, project, department WHERE department.dept_no = employee_enh.dept_no AND employee_enh.emp_no = works_on.emp_no AND works_on.project_no = project.project_no AND employee_enh.emp_lname = 'Smith';
SELECT * FROM view60;