第一题:
学生表:Student (Sno, Sname, Ssex , Sage, Sdept)
学号,姓名,性别,年龄,所在系 Sno为主键
课程表:Course (Cno, Cname,)
课程号,课程名 Cno为主键
学生选课表:SC (Sno, Cno, Score)
学号,课程号,成绩 Sno,Cno为主键
1.用SQL语句创建学生表student,定义主键,姓名不能重名,性别只能输入男或女,所在系的默认值是 "计算机"。
2.修改student 表中年龄(age)字段属性,数据类型由int 改变为smallint。
3.为SC表建立按学号(sno)和课程号(cno)组合的升序的主键索引,索引名为SC_INDEX 。
4.创建一视图 stu_info,查询全体学生的姓名,性别,课程名,成绩。
sql
1. 创建学生表 Student(满足所有约束)
mysql> CREATE TABLE Student (
-> Sno CHAR(9) PRIMARY KEY,
-> Sname VARCHAR(20) NOT NULL UNIQUE,
-> Ssex ENUM('男', '女') NOT NULL,
-> Sage INT NOT NULL,
-> Sdept VARCHAR(20) DEFAULT '计算机'
-> ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Query OK, 0 rows affected, 1 warning (0.17 sec)
sql
2. 修改Student表中Sage字段类型为SMALLINT
mysql> ALTER TABLE Student
-> MODIFY COLUMN Sage SMALLINT NOT NULL;
Query OK, 0 rows affected (0.09 sec)
Records: 0 Duplicates: 0 Warnings: 0
sql
3. 为SC表建立学号 + 课程号组合升序的主键索引(索引名SC_INDEX)
步骤 1:先创建SC表(需先存在表才能建索引)
mysql> CREATE TABLE SC (
-> Sno CHAR(9) NOT NULL,
-> Cno CHAR(4) NOT NULL,
-> Score NUMERIC(5,2),
-> PRIMARY KEY (Sno, Cno)
-> ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Query OK, 0 rows affected, 1 warning (0.03 sec)
步骤 2:创建组合主键索引SC_INDEX(升序)
创建方式:直接创建主键索引(主键默认升序)
mysql> ALTER TABLE SC
-> ADD INDEX SC_INDEX (Sno ASC, Cno ASC);
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0
sql
4. 创建视图stu_info(查询姓名、性别、课程名、成绩)
步骤1:先创建没有创建的课程表Course
mysql> CREATE TABLE Course (
-> Cno CHAR(16) PRIMARY KEY,
-> Cname VARCHAR(50) NOT NULL UNIQUE
-> ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Query OK, 0 rows affected, 1 warning (0.03 sec)
步骤2:使用左连接创建视图,达到保留未选课的学生和避免课程号无效导致数据丢失的效果
mysql> CREATE VIEW stu_info AS
-> SELECT
-> s.Sname AS 姓名,
-> s.Ssex AS 性别,
-> c.Cname AS 课程名,
-> sc.Score AS 成绩
-> FROM Student s
-> LEFT JOIN SC sc ON s.Sno = sc.Sno
-> LEFT JOIN Course c ON sc.Cno = c.Cno;
Query OK, 0 rows affected (0.01 sec)
第二题:
附:employee表和department表的数据如下。
sql
mysql> select * from employee;
+----+-------------+-----------+-----------------+-------------+------------+---------+---------+-------+---------------+
| id | number | name | job | leader_NO | hire_date | salary | bonus | level | department_NO |
+----+-------------+-----------+-----------------+-------------+------------+---------+---------+-------+---------------+
| 1 | E2018010001 | 吴所为 | 总经理 | NULL | 2018-01-01 | 2800.00 | 4000.00 | 9 | D2019060001 |
| 2 | E2018070003 | 韩金龙 | 总经理 | NULL | 2018-07-01 | 2800.00 | 4000.00 | 8 | D2019090001 |
| 3 | E2018060002 | 王黎明 | 总经理 | NULL | 2018-06-01 | 2800.00 | 4000.00 | 8 | D2019060002 |
| 4 | E2018020002 | 龚爱国 | 总经理 | NULL | 2018-02-01 | 2800.00 | 4000.00 | 8 | D2020010001 |
| 5 | E2019050001 | 马金花 | 财务总监 | E2018010001 | 2019-01-01 | 3800.00 | 500.00 | 6 | D2019060011 |
| 6 | E2019050018 | 李昌贵 | 财务专员 | E2019050001 | 2019-04-21 | 2800.00 | 800.00 | 4 | D2019060011 |
| 7 | E2019100011 | 王建国 | 网络管理员 | E2018010001 | 2019-10-01 | 3200.00 | NULL | 5 | D2019060013 |
| 8 | E2019110004 | 黎锦熙 | 网络管理员 | E2019100011 | 2019-11-01 | 3200.00 | NULL | 5 | D2019060013 |
| 9 | E2020020023 | 繁茂森 | 销售专员 | E2019060005 | 2020-02-01 | 2800.00 | 0.00 | 4 | D2019060014 |
| 10 | E2019060005 | 张善民 | 销售经理 | E2018010001 | 2019-06-01 | 2800.00 | 500.00 | 6 | D2019060014 |
| 11 | E2019060009 | 廖云龙 | 技术总监 | E2018010001 | 2019-06-01 | 4800.00 | 2000.00 | 7 | D2019060012 |
| 12 | E2019120021 | 刘盛会 | 研发工程师 | E2019060009 | 2019-12-11 | 4800.00 | 500.00 | 5 | D2019060012 |
| 13 | E2019020001 | 马明全 | 高级工程师 | E2019060009 | 2019-02-01 | 4800.00 | 1000.00 | 6 | D2019060012 |
| 14 | E2019120015 | 李意 | 行政专员 | E2018070003 | 2019-12-20 | 2800.00 | 500.00 | 4 | D2019090001 |
| 15 | E2019020017 | 刘六一 | 财务总监 | E2018070003 | 2019-02-16 | 3800.00 | 1000.00 | 6 | D2019090011 |
| 16 | E2020020012 | 陈超 | 研发工程师 | E2019060009 | 2020-02-18 | 4200.00 | 500.00 | 5 | D2019060012 |
+----+-------------+-----------+-----------------+-------------+------------+---------+---------+-------+---------------+
16 rows in set (0.01 sec)
mysql> select * from department;
+----+-------------+--------------+----------+-------------+
| id | number | name | location | super_NO |
+----+-------------+--------------+----------+-------------+
| 1 | D2019050001 | 清华集团 | 北京 | NULL |
| 2 | D2019050002 | 集团总部 | 北京 | D2019050001 |
| 3 | D2019060001 | 成都中心 | 成都 | D2019050001 |
| 4 | D2019060002 | 武汉中心 | 武汉 | D2019050001 |
| 5 | D2019090001 | 上海中心 | 上海 | D2019050001 |
| 6 | D2020010001 | 广州中心 | 广州 | D2019050001 |
| 7 | D2019090011 | 财务部 | 上海 | D2019090001 |
| 8 | D2020020012 | 行政部 | 上海 | D2019090001 |
| 9 | D2019060011 | 财务部 | 成都 | D2019060001 |
| 10 | D2019060012 | 技术部 | 成都 | D2019060001 |
| 11 | D2019060013 | 网络部 | 成都 | D2019060001 |
| 12 | D2019060014 | 市场部 | 成都 | D2019060001 |
+----+-------------+--------------+----------+-------------+
12 rows in set (0.00 sec)
1、创建一个存储过程avg_sal_a,有2个参数,分别是部门名称dept_name及接收平均工资,
其中部门名称测试参数为上海中心,接收平均薪资变量为@a。
sql
mysql> DELIMITER //
mysql> CREATE PROCEDURE avg_sal_a(
-> IN dept_name VARCHAR(50), -- 输入参数:部门名称(如"上海中心")
-> OUT avg_sal DECIMAL(10,2) -- 输出参数:接收平均薪资
-> )
-> BEGIN
-> -- 关联部门表和员工表,计算指定部门的平均薪资
-> SELECT IFNULL(AVG(e.salary), 0.00) INTO avg_sal -- IFNULL处理无数据的情况,返回0.00
-> FROM employee e
-> JOIN department d ON e.department_NO = d.number -- 关联部门编号
-> WHERE d.name = dept_name; -- 匹配输入的部门名称
-> END //
Query OK, 0 rows affected (0.08 sec)
mysql> DELIMITER ;
测试过程:
mysql> SET @a = 0.00; -- 声明用户变量@a,用于接收平均薪资
Query OK, 0 rows affected (0.00 sec)
mysql> CALL avg_sal_a('上海中心', @a); -- 调用存储过程:输入"上海中心",结果存入@a
Query OK, 1 row affected (0.01 sec)
mysql> SELECT @a AS '上海中心员工平均薪资'; -- 查询@a,查看上海中心的平均薪资
+--------------------------------+
| 上海中心员工平均薪资 |
+--------------------------------+
| 2800.00 |
+--------------------------------+
1 row in set (0.00 sec)
2、创建存储过程,给定参数员工姓名,查询该员工名所在部门的最高薪资,并返回给变量@a;
sql
mysql> DELIMITER //
mysql> CREATE PROCEDURE get_dept_max_sal_by_empname(
-> IN emp_name VARCHAR(50), -- 输入参数:员工姓名
-> OUT max_sal DECIMAL(10,2) -- 输出参数:接收部门最高薪资
-> )
-> BEGIN
-> -- 步骤1:声明局部变量,存储员工所在的部门编号
-> DECLARE dept_no VARCHAR(20);
->
-> -- 步骤2:根据员工姓名查询部门编号(处理员工不存在的情况)
-> SELECT IFNULL(e.department_NO, '') INTO dept_no
-> FROM employee e
-> WHERE e.name = emp_name;
->
-> -- 步骤3:根据部门编号查询该部门的最高薪资
-> SELECT IFNULL(MAX(e.salary), 0.00) INTO max_sal
-> FROM employee e
-> WHERE e.department_NO = dept_no;
-> END //
Query OK, 0 rows affected (0.01 sec)
mysql> DELIMITER ;
测试过程:
mysql> SET @a = 0.00; -- 声明用户变量@a
Query OK, 0 rows affected (0.00 sec)
mysql> CALL get_dept_max_sal_by_empname('韩金龙', @a); -- 调用存储过程:输入员工姓名"韩金龙",结果存入@a
Query OK, 1 row affected (0.00 sec)
mysql> SELECT @a AS '韩金龙所在部门最高薪资'; -- 查询@a,查看韩金龙所在部门(上海中心)的最高薪资
+-----------------------------------+
| 韩金龙所在部门最高薪资 |
+-----------------------------------+
| 2800.00 |
+-----------------------------------+
1 row in set (0.00 sec)