#第十三章、练习题 #基础练习 #练习1 #已经存在数据库test04_emp,两张表emp2和dept2 CREATE DATABASE test04_emp; USE test04_emp; CREATE TABLE emp2( id INT, emp_name VARCHAR(15) ); CREATE TABLE dept2( id INT, dept_name VARCHAR(15) ); #题目: #1、向表emp2的id列中添加PRIMARY KEY约束 ALTER TABLE emp2 ADD PRIMARY KEY(id); #2、向表dept2的id列中添加PRIMARY KEY约束 ALTER TABLE dept2 ADD PRIMARY KEY(id); #3、向表emp2中添加列dept_id,并在其中定义FOREIGN KEY约束,与之向关联的列是dept2表中的id列 ALTER TABLE emp2 ADD dept_id INT; DESC emp2; ALTER TABLE emp2 ADD CONSTRAINT fk_emp2_deptid FOREIGN KEY (dept_id) REFERENCES dept2(id); ###################################################################### #练习2 #承接《第11章_数据处理之增删改》的综合案例 #1、创建数据库test01_library #2、创建表books,表结构如下: /* 字段名 字段说明 数据类型 id 书编号 INT name 书名 VARCHAR(50) authors 作者 VARCHAR(100) price 价格 FLOAT pubdate 出版日期 YEAR note 说明 VARCHAR(100) num 库存 INT */ #数据库在第11章时已经创建,第1题和第2题可直接使用 USE test01_library; DESC books; #3、使用ALTER语句给books按如下要求增加相应的约束 /* 字段名 字段说明 数据类型 主键 外键 非空 唯一 自增 id 书编号 INT(11) 是 否 是 是 是 name 书名 VARCHAR(50) 否 否 是 否 否 authors 作者 VARCHAR(100) 否 否 是 否 否 price 价格 FLOAT 否 否 是 否 否 pubdate 出版日期 YEAR 否 否 是 否 否 note 说明 VARCHAR(100) 否 否 否 否 否 num 库存 INT(11) 否 否 是 否 否 */ #为id字段添加约束 #方式一(我做的) ALTER TABLE books ADD PRIMARY KEY(id); ALTER TABLE books MODIFY id INT AUTO_INCREMENT; #方式二(老师讲的另一种方法) ALTER TABLE books MODIFY id INT PRIMARY KEY AUTO_INCREMENT; #为name字段添加约束 ALTER TABLE books MODIFY name VARCHAR(50) NOT NULL; #为authors字段添加约束 ALTER TABLE books MODIFY authors VARCHAR(100) NOT NULL; #为price字段添加约束 ALTER TABLE books MODIFY price FLOAT NOT NULL; #为pubdate字段添加约束 ALTER TABLE books MODIFY pubdate YEAR NOT NULL; #为num字段添加约束 ALTER TABLE books MODIFY num INT NOT NULL; DESC books; ###################################################################### #练习3 #题目 #1、创建数据库test04_company CREATE DATABASE IF NOT EXISTS test04_company; USE test04_company; #2、按照下表给出的表结构在test04_company数据库中创建两个数据表offices和employees #offices表: /* 字段名 数据类型 主键 外键 非空 唯一 自增 officeCode INT(10) 是 否 是 是 否 city VARCHAR(50) 否 否 是 否 否 address VARCHAR(50) 否 否 否 否 否 country VARCHAR(50) 否 否 是 否 否 postalCode VARCHAR(15) 否 否 否 是 否 */ #employees表: /* 字段名 数据类型 主键 外键 非空 唯一 自增 employeeNumber INT(11) 是 否 是 是 是 lastName VARCHAR(50) 否 否 是 否 否 firstName VARCHAR(50) 否 否 是 否 否 mobile VARCHAR(25) 否 否 否 是 否 officeCode INT(10) 否 是 是 否 否 jobTitle VARCHAR(50) 否 否 是 否 否 birth DATETIME 否 否 是 否 否 note VARCHAR(255) 否 否 否 否 否 sex VARCHAR(5) 否 否 否 否 否 */ CREATE TABLE IF NOT EXISTS offices( officeCode INT PRIMARY KEY, #老师写的:officeCode INT(10) PRIMARY KEY, city VARCHAR(50) NOT NULL, address VARCHAR(50), country VARCHAR(50) NOT NULL, postalCode VARCHAR(15) UNIQUE ); DESC offices; CREATE TABLE IF NOT EXISTS employees( employeeNumber INT PRIMARY KEY AUTO_INCREMENT, lastName VARCHAR(50) NOT NULL, firstName VARCHAR(50) NOT NULL, mobile VARCHAR(25) UNIQUE, officeCode INT NOT NULL, jobTitle VARCHAR(50) NOT NULL, birth DATETIME NOT NULL, note VARCHAR(255), sex VARCHAR(5), CONSTRAINT fk_emp_offcode FOREIGN KEY(officeCode) REFERENCES offices(officeCode) ); DESC employees; #3、将表employees的mobile字段修改到officeCode字段后面 ALTER TABLE employees MODIFY mobile VARCHAR(25) AFTER officeCode; #4、将表employees的birth字段名改为employee_birth ALTER TABLE employees CHANGE birth employee_birth DATETIME; #5、修改sex字段,数据类型为CHAR(1),非空约束 ALTER TABLE employees MODIFY sex CHAR(1) NOT NULL; #6、删除字段note ALTER TABLE employees DROP COLUMN note; #7、增加字段名favoriate_activity,数据类型为VARCHAR(100) ALTER TABLE employees ADD favoriate_activity VARCHAR(100); #8、将表employees名称修改为employees_info RENAME TABLE employees TO employees_info; DESC employees_info; ###################################################################### #拓展练习 #练习1 #创建数据库test04_Market,在test04_Market中创建数据表customers。 #customers表结构如下所示,按以下要求进行操作。 /* 字段名 数据类型 主键 外键 非空 唯一 自增 c_num INT(11) 是 否 是 是 是 c_name VARCHAR(50) 否 否 否 否 否 c_contact VARCHAR(50) 否 否 否 否 否 c_city VARCHAR(50) 否 否 否 否 否 c_birth DATETIME 否 否 是 否 否 */ #1、创建数据库test04_Market。 CREATE DATABASE test04_Market; USE test04_Market; #2、创建数据表customers,在c_num字段上添加主键约束和自增约束,在c_birth字段上添加非空约束。 CREATE TABLE customers( c_num INT PRIMARY KEY AUTO_INCREMENT, c_name VARCHAR(50), c_contact VARCHAR(50), c_city VARCHAR(50), c_birth DATETIME NOT NULL ); DESC customers; #3、将c_contact字段插入c_birth字段后面。 ALTER TABLE customers MODIFY c_contact VARCHAR(50) AFTER c_birth; #4、将c_name字段数据类型改为VARCHAR(70)。 ALTER TABLE customers MODIFY c_name VARCHAR(70); #5、将c_contact字段改名为c_phone。 ALTER TABLE customers CHANGE c_contact c_phone VARCHAR(50); #6、增加c_gender字段,数据类型为CHAR(1)。 ALTER TABLE customers ADD COLUMN c_gender CHAR(1); #7、将表名修改为customers_info。 RENAME TABLE customers TO customers_info; DESC customers_info; #8、删除字段c_city。 ALTER TABLE customers_info DROP c_city; #在test04_Market中创建数据表orders。orders表结构如下所示,按以下要求进行操作。 /* 字段名 数据类型 主键 外键 非空 唯一 自增 o_num INT(11) 是 否 是 是 是 o_date DATE 否 否 否 否 否 c_id INT(11) 否 是 否 否 否 */ #1、创建数据表orders,在o_num字段上添加主键约束和自增约束,在c_id字段上添加外键约束,关联customers表中的主键c_num。 CREATE TABLE IF NOT EXISTS orders( o_num INT PRIMARY KEY AUTO_INCREMENT, o_date DATE, c_id INT, CONSTRAINT fk_orders_c_id FOREIGN KEY(c_id) REFERENCES customers_info(c_num) ); DESC orders; #2、删除orders表的外键约束,然后删除表customers。 #查看约束信息,主要是查看外键约束名 SELECT * FROM information_schema.TABLE_CONSTRAINTS WHERE table_name = 'orders'; #删除外键约束 ALTER TABLE orders DROP FOREIGN KEY fk_orders_c_id; #查看索引名 SHOW INDEX FROM orders; #删除索引 ALTER TABLE orders DROP INDEX fk_orders_c_id; ###################################################################### #练习2 #创建数据表pet,并对表进行插入、更新与删除操作。pet表结构如下所示。 #pet表结构 /* 字段名 字段说明 数据类型 主键 外键 非空 唯一 自增 name 宠物名称 ARCHAR(20) 否 否 是 否 否 owner 宠物主人 ARCHAR(20) 否 否 否 否 否 species 种类 ARCHAR(20) 否 否 是 否 否 sex 性别 CHAR(1) 否 否 是 否 否 birth 出生日期 YEAR 否 否 是 否 否 death 死亡日期 TEAR 否 否 否 否 否 */ #pet表中记录 /* name owner species sex birth death Fluffiy Harold cat f 2003 2010 Claws Gwen cat m 2004 NULL Buffiy NULL dog f 2009 NULL Fang Benny dog m 2000 NULL Bowser Diane dog m 2003 2009 Chirpy NULL bird f 2008 NULL */ #1、首先创建数据表pet,使用不同的方法将表记录插入到pet表中。 #创建表 CREATE TABLE pet( `name` VARCHAR(20) NOT NULL, `owner` VARCHAR(20), species VARCHAR(20) NOT NULL, sex CHAR(1) NOT NULL, birth YEAR NOT NULL, death YEAR ); DESC pet; #向表中插入数据 INSERT INTO pet(name,owner,species,sex,birth,death) VALUES('Fluffiy','Harold','cat','f','2003','2010'); INSERT INTO pet VALUES ('Claws','Gwen','cat','m','2004',NULL), ('Buffiy',NULL,'dog','f','2009',NULL), ('Fang','Benny','dog','m','2000',NULL), ('Bowser','Diane','dog','m','2003',2009), ('Chirpy',NULL,'bird','f','2008',NULL); SELECT * FROM pet; #2、使用UPDATE语句将名称为Fang的狗的主人改为Kevin。 UPDATE pet SET owner = 'Kevin' WHERE name = 'Fang'; #3、将没有主人的宠物owner字段值都改为Duck。 UPDATE pet SET owner = 'Duck' WHERE owner IS NULL; #4、删除已死亡的宠物记录。 DELETE FROM pet WHERE death IS NOT NULL; #5、删除所有表中的记录。 DELETE FROM pet; SELECT * FROM pet; ###################################################################### #练习3 #1、创建数据库:test_company CREATE DATABASE IF NOT EXISTS test_company; USE test_company; #2、在此数据库下创建如下3表,数据类型,宽度,是否为空根据实际情况自己定义。 /* A、部门表(department):部门编号(depid)。部门名称(depname)。 部门简介(depinfo);其中部门编号为主键。 B、雇员表(employee):雇员编号(empid),姓名(name),性别(sex), 职称(title),出生日期(birthday),所在部门编号(depid);其中: 雇员编号为主键; 部门编号为外键,外键约束等级为(on update cascade和on delete set null); 性别默认为男; C、工资表(salary):雇员编号(empid),基本工资(basesalary),职务 工资(titlesalary),扣除(deduction)。其中雇员编号为主键。 */ #部门表 CREATE TABLE department( depid INT, depname VARCHAR(20) NOT NULL, depinfo VARCHAR(50), PRIMARY KEY(depid) ); DESC department; #雇员表 CREATE TABLE employee( empid INT PRIMARY KEY, name VARCHAR(20) NOT NULL, sex CHAR(1) NOT NULL DEFAULT '男', title VARCHAR(15), birthday DATE NOT NULL, depid INT, CONSTRAINT fk_emp_depid FOREIGN KEY(depid) REFERENCES department(depid) ON UPDATE CASCADE ON DELETE SET NULL ); DESC employee; #工资表 CREATE TABLE salary( empid INT PRIMARY KEY, basesalary DECIMAL(10,2), titlesalary DECIMAL(10,2), deduction DECIMAL(10,2) ); DESC salary; #3、给工资表(salary)的雇员编号(empid)增加外键约束,外键约束等级为 #(on update cascade和on delete cascade) ALTER TABLE salary ADD CONSTRAINT fk_sal_empid FOREIGN KEY(empid) REFERENCES employee(empid) ON UPDATE CASCADE ON DELETE CASCADE; #4、添加数据如下: #部门表: /* 部门编号 部门名称 部门简介 111 生产部 NULL 222 销售部 NULL 333 人事部 人力资源管理 */ #雇员表: /* 雇员编号 姓名 性别 职称 出生日期 所在部门编号 1001 张三 男 高级工程师 1975-1-1 111 1002 李四 女 助工 1985-1-1 111 1003 王五 男 工程师 1978-11-11 222 1004 张六 男 工程师 1999-1-1 222 */ #工资表: /* 雇员编号 基本工资 职务工资 扣除 1001 2200 1100 200 1002 1200 200 NULL 1003 2900 700 200 1004 1950 700 150 */ #添加部门表数据 INSERT INTO department VALUES (111,'生产部',NULL), (222,'销售部',NULL), (333,'人事部','人力资源管理'); SELECT * FROM department; #添加雇员表数据 INSERT INTO employee VALUES (1001,'张三',DEFAULT,'高级工程师','1975-1-1',111), (1002,'李四','女','助工','1985-1-1',111), (1003,'王五','男','工程师','1978-11-11',222), (1004,'张六',DEFAULT,'工程师','1999-1-1',222); SELECT * FROM employee; #添加工资表数据 INSERT INTO salary VALUES (1001,2200,1100,200), (1002,1200,200,NULL), (1003,2900,700,200), (1004,1950,700,150); SELECT * FROM salary; #5、查询出每个雇员的雇员编号、姓名、职称、所在部门名称、应发工资(基本工资+职务工资),实发工资(基本工资+职务工资-扣除) SELECT emp.empid,emp.name,emp.title,dep.depname,sal.basesalary+sal.titlesalary AS '应发工资',sal.basesalary+sal.titlesalary-IFNULL(sal.deduction,0) AS '实发工资' FROM employee AS emp JOIN department dep JOIN salary AS sal ON emp.depid = dep.depid AND emp.empid = sal.empid; #6、查询销售部门的雇员姓名及其基本工资 SELECT emp.name,sal.basesalary FROM department dep JOIN employee emp JOIN salary sal ON dep.depid = emp.depid AND emp.empid = sal.empid WHERE dep.depname = '销售部'; #7、查询姓“张”且年龄小于40的员工的全部信息和年龄 SELECT *,YEAR(NOW())-YEAR(birthday) AS '年龄' FROM employee WHERE name LIKE '张%' AND (YEAR(NOW())-YEAR(birthday)) < 40; #8、查询所有男员工的基本工资和职务工资 SELECT * FROM employee; SELECT emp.empid,emp.name,sal.basesalary,sal.titlesalary FROM employee emp JOIN salary sal ON emp.empid = sal.empid WHERE emp.sex = '男'; #9、查询基本工资低于2000的员工姓名和职称、所在部门名称 SELECT emp.name,emp.title,dep.depname FROM department dep JOIN employee emp JOIN salary sal ON dep.depid = emp.depid AND emp.empid = sal.empid WHERE sal.basesalary < 2000; #10、查询员工总数 SELECT COUNT(*) FROM employee; #11、查询部门总数 SELECT COUNT(*) FROM department; #12、查询应发工资的平均工资和最高工资、最低工资 SELECT AVG(basesalary+titlesalary) AS '平均工资',MAX(basesalary+titlesalary) AS '最高工资',MIN(basesalary+titlesalary) AS '最低工资' FROM salary; #13、按照部门统计应发工资的平均工资 SELECT depid,AVG(basesalary+titlesalary) FROM employee JOIN salary ON employee.empid = salary.empid GROUP BY employee.depid #14、找出部门基本工资的平均工资低于2000的 SELECT depid,AVG(basesalary) AS avgsal FROM employee JOIN salary ON employee.empid = salary.empid GROUP BY employee.depid HAVING avgsal < 2000; #15、按照员工编号、姓名、基本工资、职务工资、扣除,并按照职务升序排列,如果职务工资相同,再按照基本工资升序排列。 SELECT emp.empid,emp.name,emp.title,basesalary,titlesalary,deduction FROM employee emp JOIN salary sal ON emp.empid = sal.empid ORDER BY emp.title ASC,basesalary ASC; #16、查询员工编号、姓名,出生日期,及年龄段。其中,如果80年之前出生的,定为“老年”;80后定为“中年”,90后定为“青壮年” SELECT empid,name,birthday, CASE WHEN YEAR(birthday) < 1980 THEN '老年' WHEN YEAR(birthday) < 1990 THEN '中年' ELSE '青壮年' END AS '年龄段' FROM employee; #17、查询所有的员工信息,和他所在的部门名称 SELECT emp.*,dep.depname FROM employee emp LEFT JOIN department dep ON emp.depid = dep.depid #18、查询所有部门信息,和该部门的员工信息 SELECT dep.*,emp.* FROM department dep LEFT JOIN employee emp ON dep.depid = emp.depid #19、查询所有职位中含“工程师”的男员工的人数 SELECT COUNT(*) FROM employee WHERE sex = '男' AND title LIKE '%工程师%'; #20、查询每个部门的男生和女生的人数和平均基本工资 SELECT dep.depid,emp.sex,COUNT(*),AVG(sal.basesalary) FROM department dep JOIN employee emp JOIN salary sal ON dep.depid = emp.depid AND emp.empid = sal.empid GROUP BY dep.depid,emp.sex ###################################################################### #练习4: #1、创建一个数据库:test_school CREATE DATABASE IF NOT EXISTS test_school; USE test_school; #2、创建如下表格: #表1 Department表的定义 /* 字段名 字段描述 数据类型 主键 外键 非空 唯一 DepNo 部门号 INT(10) 是 否 是 是 DepName 部门名称 VARCHAR(20) 否 否 是 否 DepNote 部门备注 VARCHAR(50) 否 否 否 否 */ #表2 Teacher表的定义 /* 字段名 字段描述 数据类型 主键 外键 非空 唯一 Number 教工号 INT 是 否 是 是 Name 姓名 VARCHAR(30) 否 否 是 否 Sex 性别 VARCHAR(4) 否 否 否 否 Birth 出生日期 DATE 否 否 否 否 DepNo 部门号 INT 否 是 否 否 Salary 工资 FLOAT 否 否 否 否 Address 家庭住址 VARCHAR(100) 否 否 否 否 */ #创建表1 CREATE TABLE Department( DepNo INT(10) PRIMARY KEY, DepName VARCHAR(20) NOT NULL, DepNote VARCHAR(50) ); DESC Department; #创建表2 CREATE TABLE Teacher( Number INT PRIMARY KEY, Name VARCHAR(30) NOT NULL, Sex VARCHAR(4), Birth DATE, DepNo INT, Salary FLOAT, Address VARCHAR(100), CONSTRAINT fk_teach_depno FOREIGN KEY(DepNo) REFERENCES Department(Depno) ); DESC Teacher; #3、添加记录 /* DepNo DepName DepNote 601 软件技术系 软件技术等专业 602 网络技术系 多媒体技术等专业 603 艺术设计系 广告艺术设计等专业 604 管理工程系 连锁经营管理等专业 */ /* Number Name Sex Birth DepNo Salary Address 2001 Tom 女 1970-01-10 602 4500 四川省绵阳市 2002 Lucy 男 1983-12-18 601 2500 北京市昌平区 2003 Mike 男 1990-06-01 604 1500 重庆市渝中区 2004 James 女 1980-10-20 602 3500 四川省成都市 2005 Jack 男 1975-05-30 603 1200 重庆市南岸区 */ #向部门表添加记录 INSERT INTO Department VALUES (601,'软件技术系','软件技术等专业'), (602,'网络技术系','多媒体技术等专业'), (603,'艺术设计系','广告艺术设计等专业'), (604,'管理工程系','连锁经营管理等专业'); SELECT * FROM Department; #向教师表中添加记录 INSERT INTO Teacher VALUES (2001,'Tom','女','1970-01-10',602,4500,'四川省绵阳市'), (2002,'Lucy','男','1983-12-18',601,2500,'北京市昌平区'), (2003,'Mike','男','1990-06-01',604,1500,'重庆市渝中区'), (2004,'James','女','1980-10-20',602,3500,'四川省成都阳市'), (2005,'Jack','男','1975-05-30',603,1200,'重庆市南岸区'); SELECT * FROM Teacher; #4、用SELECT语句查询Teacher表的所有记录 SELECT * FROM Teacher; #5、找出所有其家庭地址中含有“北京”的教师的教工号及部门名称,要求显示结果中各列标题用中文别名表示。 SELECT teach.Number AS '教工号',dep.DepName AS '部门名称',teach.Address FROM Teacher teach LEFT JOIN Department dep ON teach.DepNo = dep.DepNo WHERE teach.Address LIKE '%北京%'; #6、获得Teacher表中工资最高的教工号和姓名。 #我做的 SELECT Number,Name,MAX(Salary) FROM Teacher #老师给的 #方法一 SELECT Number,Name FROM Teacher WHERE salary =(SELECT MAX(Salary) FROM Teacher); #方法二 SELECT Number,Name FROM Teacher ORDER BY Salary DESC LIMIT 0,1; #7、找出所有收入在2500~4000之间的教工号。 SELECT Number FROM Teacher WHERE Salary BETWEEN 2500 AND 4000; #8、查找在网络技术系工作的教师的姓名、性别和工资。 SELECT Name,Sex,Salary FROM Teacher teach JOIN Department dep ON teach.DepNo = dep.DepNo WHERE dep.DepName = '网络技术系' ###################################################################### #练习5 #1、建立数据库test_student CREATE DATABASE IF NOT EXISTS test_student; USE test_student; #2、建立以下三张表,并插入记录 #Table:Classes /* 专业 班级 姓名 性别 座位 计算机网络 1班 张三 男 8 软件工程 2班 李四 男 12 计算机维护 1班 王五 男 9 计算机网络 2班 LILY 女 15 软件工程 1班 小强 男 20 计算机维护 1班 CoCo 女 18 */ #Table:Score /* 姓名 英语 数据 语文 张三 65 75 98 李四 87 45 86 王五 98 86 65 LILY 75 86 87 小强 85 60 58 CoCo 96 87 70 */ #Table:Records /* 姓名 记录 小强 迟到 小强 事假 李四 旷课 李四 旷课 李四 迟到 CoCo 病假 LILY 事假 */ #创建表一:Classes CREATE TABLE classes( major VARCHAR(20) NOT NULL, class VARCHAR(10) NOT NULL, sname VARCHAR(10) NOT NULL, sex CHAR(1) DEFAULT '男', seat INT UNIQUE NOT NULL ); #创建表二:score CREATE TABLE score( sname VARCHAR(10) NOT NULL, english INT NOT NULL, math INT NOT NULL, chinese INT NOT NULL ); #创建表三:Records CREATE TABLE records( sname VARCHAR(10) NOT NULL, record VARCHAR(10) ); #向classes表插入数据 INSERT INTO classes VALUES ('计算机网络','1班','张三',DEFAULT,8), ('软件工程','2班','李四',DEFAULT,12), ('计算机维护','1班','王五','男',9), ('计算机网络','2班','LILY','女',15), ('软件工程','1班','小强',DEFAULT,20), ('计算机维护','1班','CoCo','女',18); SELECT * FROM classes; #向score表插入数据 INSERT INTO score VALUES ('张三',65,75,98), ('李四',87,45,86), ('王五',98,86,65), ('LILY',75,86,87), ('小强',85,60,58), ('Coco',96,87,70); SELECT *FROM score; #向records表插入数据 INSERT INTO records VALUES ('小强','迟到'), ('小强','事假'), ('李四','旷课'), ('李四','旷课'), ('李四','迟到'), ('Coco','病假'), ('LILY','事假'); SELECT * FROM records; #3、写出将张三的语文成绩修改为88的SQL语句 UPDATE score SET chinese = 88 WHERE sname = '张三'; #4、搜索出计算机维护1班各门课程的平均成绩 #我做的,不对 SELECT major,class,AVG(english),AVG(math),AVG(chinese) FROM score JOIN classes GROUP BY major,class HAVING major = '计算机维护' AND class = '1班' #老师给的参考方法 SELECT AVG(english),AVG(math),AVG(chinese) FROM score WHERE sname IN (SELECT sname FROM classes WHERE major = '计算机维护' AND class = '1班'); #5、搜索科目有不及格的人的名单 SELECT sname FROM score WHERE english < 60 OR math < 60 OR chinese <60; #6、查询记录2次以上的学生的姓名和各科成绩 SELECT score.* FROM score JOIN (SELECT sname,COUNT(*) FROM records GROUP BY sname HAVING COUNT(*) >= 2) temp ON score.sname = temp.sname; ###################################################################### #练习6 #1、建立数据库:test_xuankedb CREATE DATABASE IF NOT EXISTS test_xuankedb; USE test_xuankedb; #2、建立如下三张表: /* 学生表Student由学号(Sno)、姓名(Sname)、性别(Ssex)、 年龄(Sage)、所在系(Sdept)五个字段,Sno为关键字。 课程表(Course)由课程号(Cno)、课程名(Cname)、选修课号(Cpno)、 学分(Ccredit)四个字段,Cno为关键字。 成绩表SG由学号(Sno)、课程号(Cno)、成绩(Grade)三个字段, (Sno,Cno)为关键字。 */ #创建学生表 CREATE TABLE IF NOT EXISTS student( sno INT PRIMARY KEY, sname VARCHAR(20) NOT NULL, ssex CHAR(1) NOT NULL, sage INT NOT NULL, sdept VARCHAR(40) NOT NULL ); DESC student; #创建课程表 CREATE TABLE IF NOT EXISTS course( cno INT PRIMARY KEY, cname VARCHAR(20) NOT NULL, cpno VARCHAR(40), ccredit INT ); DESC course; #创建成绩表 CREATE TABLE IF NOT EXISTS sg( sno INT, cno INT, grade INT, PRIMARY KEY(sno,cno), CONSTRAINT fk_s_stu_sno FOREIGN KEY(sno) REFERENCES student(sno), CONSTRAINT fk_s_cou_sno FOREIGN KEY(cno) REFERENCES course(cno) ); DESC sg; #3、向Student表增加“入学时间(Scome)”列,其数据类型为日期型。 ALTER TABLE student ADD scome DATE; #4、查询选修了3号课程的学生的学号及其成绩,查询结果按分数的降序排列。 SELECT sno,grade FROM sg WHERE cno = 3 ORDER BY grade DESC; #5、查询学习1号课程的学生最高分数、平均成绩。 SELECT MAX(grade),AVG(grade) FROM sg WHERE cno = 1; #6、查询与“李洋”在同一个系学习的学生。 SELECT * FROM student WHERE sdept = (SELECT dept FROM student WHERE sname = '李洋' ); #7、将计算机系全体学生的成绩置零。 UPDATE sg set grade = 0 WHERE sno IN (SELECT sno FROM student WHERE sdept = '计算机系'); #8、删除学生表中学号为05019的学生记录。 DELETE FROM student WHERE sno = 05019 #9、删除计算机系所有学生的成绩记录。 DELETE FROM sg WHERE sno IN (SELECT sno FROM student WHERE dept = '计算机系'); ###################################################################### #练习7 #1、建立数据库:test_library CREATE DATABASE IF NOT EXISTS test_library; USE test_library; #2、建立如下三个表: /* 表一:press出版社 属性:编号pressid(int)、名称pressname(varchar)、 地址address(varchar) 表二:sort种类 属性:编号sortno(int)、数量scount(int) 表三:book图书 属性:编号bid(int)、名称bname(varchar)、 种类bsortno(int)、出版社编号pressid(int) */ #创建表一 CREATE TABLE press( pressid INT PRIMARY KEY, pressname VARCHAR(30), address VARCHAR(50) ); #创建表二 CREATE TABLE sort( sortno INT PRIMARY KEY, scount INT ); #创建表三 CREATE TABLE book( bid INT PRIMARY KEY, bname VARCHAR(20), bsortno INT, pressid INT, CONSTRAINT fk_p_b_pid FOREIGN KEY(pressid) REFERENCES press(pressid), CONSTRAINT fk_s_b_sno FOREIGN KEY(bsortno) REFERENCES sort(sortno) ); #3、给sort表中添加一列属性:描述describes(varchar) ALTER TABLE sort ADD describes VARCHAR(30); DESC sort; #4、向三个表中各插入几条数据 #表一:press /* pressid pressname address 100 外研社 上海 101 北大出版社 北京 102 教育出版社 北京 */ #表二:sort /* sortno scount describes 11 50 小说 12 300 科幻 13 100 神话 */ #表三:book /* bid bname bsortno pressid 1 红与黑 11 100 2 幻城 12 102 3 希腊神话 13 102 4 一千零一夜 13 102 */ #向表一插入数据 INSERT INTO press VALUES (100,'外研社','上海'), (101,'北大出版社','北京'), (102,'教育出版社','北京'); #向表二插入数据 INSERT INTO sort VALUES (11,50,'小说'), (12,300,'科幻'), (13,100,'神话'); #向表三插入数据 INSERT INTO book VALUES (1,'红与黑',11,100), (2,'幻城',12,102), (3,'希腊神话',13,102), (4,'一千零一夜',13,102); #5、查询出版社id为100的书的全部信息 SELECT * FROM press; SELECT * FROM sort; SELECT * FROM book; SELECT * FROM book WHERE pressid = 100; #6、查询出版社为外研社的书的全部信息 SELECT * FROM book WHERE pressid = ( SELECT pressid FROM press WHERE pressname = '外研社' ); #7、查询图书数量(scount)大于100的种类 SELECT * FROM sort WHERE scount > 100; #8、查询图书种类最多的出版社信息 #我做的 SELECT * FROM press WHERE pressid = ( SELECT pressid FROM book GROUP BY bsortno ORDER BY count(*) DESC LIMIT 0,1 ); #老师给的参考答案 #方式一(报错,无法运行) SELECT * FROM press WHERE pressid=( SELECT temp.pressid FROM (SELECT pressid,MAX(t,c) FROM (SELECT pressid,COUNT(*) AS c FROM book GROUP BY pressid ORDER BY c DESC) AS t) AS temp); #方式二(可以运行) SELECT * FROM press WHERE pressid = ( SELECT pressid FROM (SELECT pressid,bsortno FROM book GROUP BY pressid,bsortno) temp GROUP BY pressid ORDER BY COUNT(*) DESC LIMIT 0,1); ###################################################################### #练习8 #1、建立数据库:test_tour CREATE DATABASE IF NOT EXISTS test_tour; USE test_tour; #2、建立如下两个表 #agency旅行社表: /* 列名(英文名) 列名(中文名) 数据类型 允许空值 说明 Id 旅行社编号 INT NO 主键 Name 旅行社名 VARCHAR NO Address 旅行社地址 VARCHAR NO Areaid 所属区域id INT YES */ #travel旅行线路表 /* 列名(英文名) 列名(中文名) 数据类型 允许空值 说明 Tid 旅行线路编号 INT NO 主键 Time 所需时间 VARCHAR NO Position 目的地 VARCHAR NO Money 花费 FLOAT YES Aid 所属旅行社id INT NO 外键 Count 报名人数 INT YES */ #创建旅行社表 CREATE TABLE agency( id INT PRIMARY KEY, `name` VARCHAR(20) NOT NULL, address VARCHAR(100) NOT NULL, areaid INT ); DESC agency; #创建旅行线路表 CREATE TABLE travel( tid INT PRIMARY KEY, time VARCHAR(50) NOT NULL, `position` VARCHAR(100) NOT NULL, money FLOAT, aid INT NOT NULL, count INT, CONSTRAINT fk_tr_aid FOREIGN KEY travel(aid) REFERENCES agency(id) ); DESC travel; #3、添加记录 #agency表数据 /* id name address 101 青年旅行社 北京海淀 102 天天旅行社 天津海院 */ #travel表数据 /* tid time position money aid rcount 1 5天 八达岭 3000 101 10 2 7天 水长城 5000 101 14 3 8天 水长城 6000 102 11 */ #向表agency添加记录 INSERT INTO agency(id,`name`,address) VALUES (101,'青年旅行社','北京海淀'), (102,'天天旅行社','天津海院'); SELECT * FROM agency; #向表travel添加记录 INSERT INTO travel VALUES (1,'5天','八达岭',3000,101,10), (2,'7天','水长城',5000,101,14), (3,'8天','水长城',6000,102,11); SELECT * FROM travel; #4、查出旅行线路最多的旅社 #我做的,分了四步,后一步的代码都包含了前一步的代码 #第一步:对旅行线路表中的旅行社进行分组 SELECT aid,COUNT(*) AS c FROM travel GROUP BY aid #第二步:在第一步的分组结果中,取旅行社统计数量最大值的数量和id SELECT MAX(new.c),new.aid FROM ( SELECT aid,COUNT(*) AS c FROM travel GROUP BY aid ) AS new #第三步:从第二步的表中取出旅行社的id SELECT maxsheet.aid FROM (SELECT MAX(new.c),new.aid FROM ( SELECT aid,COUNT(*) AS c FROM travel GROUP BY aid ) AS new ) as maxsheet; #第四步:根据第三步取出的旅行社id,在旅行社表中查出旅行社信息 SELECT * FROM agency WHERE id = (SELECT maxsheet.aid FROM (SELECT MAX(new.c),new.aid FROM ( SELECT aid,COUNT(*) AS c FROM travel GROUP BY aid ) AS new ) as maxsheet ); #老师给的参考答案 SELECT * FROM agency INNER JOIN (SELECT t.aid,MAX(t.c) FROM (SELECT aid,COUNT(*) AS c FROM travel GROUP BY aid) AS t) temp ON agency.id = temp.aid; #5、查出最热门的旅行线路(也就是查询出报名人数最多的线路) #我做的 SELECT * FROM travel ORDER BY count DESC LIMIT 0,1; #老师提供的答案 SELECT * FROM travel WHERE count = ( SELECT MAX(count) FROM travel ); #6、查询花费少于5000的旅行线路 SELECT * FROM travel WHERE money < 5000; #7、找到一次旅行花费最昂贵的旅行社名 #先找到最贵的费用是多少 SELECT MAX(money) FROM travel; #再查找最贵费用的旅行社aid SELECT aid FROM travel WHERE money = ( SELECT MAX(money) FROM travel ); #然后根据旅行社aid查找旅行社名称 SELECT name FROM agency WHERE id = ( SELECT aid FROM travel WHERE money = ( SELECT MAX(money) FROM travel ) ); #老师给的答案 SELECT name FROM agency WHERE id = ( SELECT aid FROM travel WHERE money = ( SELECT MAX(money) FROM travel ) ); #8、查出青年旅社所有的旅行线路都玩一遍需要多少时间 #先查出青年旅社的id SELECT id FROM agency WHERE name = '青年旅行社'; #根据旅行社id在线路表进行查找求和 SELECT SUM(time) FROM travel WHERE aid = ( SELECT id FROM agency WHERE name = '青年旅行社' ); #老师给的答案 SELECT SUM(time) FROM travel WHERE aid = ( SELECT id FROM agency WHERE name = '青年旅行社' );