MySQL笔记整理+练习

第一范式(1NF)
原子性:保证每一列不可再分
第二范式(2NF)
前提:满足第一范式每张表只描述一件事情
前提:满足第一范式和第二范式
第三范式(3NF)
需要确保数据表中的每一列数据都和主键直接相关,而不能间接相关。
#查询所有数据库
show databases;
#查询当前数据库
select database() ;
#创建                  #如果不存在               #字符集                 #排序规则
create database if not exists stu1 default charset utf8mb4;   [collate]
#删除                  #如果存在
drop database if exists stu1;
#使用
use dbtext1;
#查询当前数据库所有表
show tables;
#查询表结构
desc stu ;
#查询指定表的建表语句
show create table stu ;
create table stu (
id int comment '编号',
name varchar(50) comment '名字',
age int comment '年龄',
gender varchar(1) comment '性别'
);
desc stu;
#增加
alter table stu add nick varchar(20);
alter table stu add nickname varchar(20) comment '昵称';
alter table stu add idcard char(18);#身份证号
alter table stu add enteydate date;#出生日期
#修改数据类型
alter table stu modify nickname varchar(10);
alter table stu modify age tinyint unsigned;
#修改字段名和类型
alter table stu change nick username varchar(30) comment '用户名';
alter table stu add nick varchar(20);
#删除字段
alter table stu drop nick;
alter table stu drop nickname;
#修改表明
alter table stu rename to stus;
alter table stus rename to stu;
#删除表
drop table if exists stu1;
#删除指定表,并重新创建该表
truncate table stu1;
1、清空操作: DELETE FROM table_name ; 不会重置自增字段,效率低,有日志记录,会激活触发器。 对于数据量大的表,执行的比较慢。
2、截断操作:TRUNCATE [TABLE] table_name ; 会重置自增字段,效率高,无日志记录,不会激活触发器。 请谨慎使用,一旦执行,数据无法恢复。 数据无价,请慎之又慎!! (不要一不小心删库跑路 _)
#数据
select * from stu;
#插入,增加
insert into stu (id,name,age,gender)
values (1,'张三',23,'男');
insert into stu (username,idcard,enteydate)
values ('学生',125455665565655556,'2001-03-12');
truncate table stu;
insert into stu (id,name,age,gender,username,idcard,enteydate)
values (1,'张三',23,'男','班长',125455665565655556,'2001-03-12');
insert into stu values (2,'李四',22,'男','副班长',123456789012345678,'2001-09-12'),
(3,'王五',21,'男','成员',125455665588855556,'2001-07-02');
#修改
update stu set username = '学员' where id = 3;
update stu set gender = '女';
#删除
insert into stu (id,name)
values (4,'哈哈');
delete from stu where id = 4;
#删除所有数据
delete from stu ;
#DCL
#查询用户
use mysql;
select * from `user` u ;
#创建在本机上访问的用户
create user 'yh'@'localhost' identified by '123456';
#任意主机
create user 'yh'@'%' identified by '123456';
#修改密码
alter user 'yh'@'localhost' identified with mysql_native_password by '123';
#删除
drop user 'yh'@'localhost' ;
#查询权限
show grants for 'yh'@'localhost';
#授予权限
      #权限   #数据库名.表明
grant all on dbtext1.* to 'yh'@'localhost';
#撤销权限
revoke all on dbtext1.* from 'yh'@'localhost';
#多个权限用逗号分割.库名表明都可用*进行通配代表所有
#all,all privileges所有权限
#select查询权限.insert插入权限.update修改权限.delete删除权限.
#alter修改表.dorp删除数据库/表/视图.create创建数据库/表
-- 自增长
-- auto-increment
-- 非空约束
-- NOT NULL
-- 唯一约束
-- UNIQUE
-- 主键约束
-- PRIMARY KEY
-- 检查约束 MySQL不支持
-- CHECK
-- 默认约束
-- DEFAULT
-- 外键约束
-- FOREIGN KEY
CONSTRAINT fk_emp_dept FOREIGN KEY(dep_id) REFERENCES dept(id)
use atguigudb;
select * from employees;
#distinct去重
select distinct department_id
from employees;
#distinct department_id , salary仅仅没报错,没实际意义
select distinct department_id , salary
from employees;
#空值参与运算(null),null不等同于0," "
select * from employees;
#空值参与运算值也为空
select employee_id,salary "月工资",salary * (1 + commission_pct)*12 "年工资",commission_pct
from employees;
#解决方案,引入ifnull
select employee_id,salary "月工资",salary * (1 + ifnull(commission_pct,0))*12 "年工资",commission_pct
from employees;#if commission_pct为null then 用0替代
#着重号''解决表名等使用了关键字
select * from `order`;#order为关键字
#查询常数
select '五斗米',123,employee_id ,last_name
from employees;
#现实表结构
describe employees ;#描述了表中字段的详细信息
desc employees ;
#过滤数据
#查询90号部门员工信息
select *
from employees
#过滤条件紧跟from后
where department_id = 90;
#查询last_name='King'的员工信息
select *
from employees
where last_name = 'King';
select last_name
from employees
where last_name like '__a%';
select last_name
from employees
where last_name like '%a%k%' or last_name like '%k%a%';
select * from employees where employee_id  = 100;
select * from employees;
desc employees ;
select last_name,department_id,salary*12 '年薪'
from employees
order by '年薪' desc,last_name asc ;
select last_name,salary
from employees
#where salary not between 8000 and 17000
where salary <8000 or salary >17000
order by salary desc
limit 20,20;
select employee_id ,last_name ,email ,department_id
from employees
where email like '%e%'
order by length(email) desc,department_id asc;
#多表查询
select employee_id,department_name
from employees,departments
where employees.department_id = departments.department_id ;
#如果查询语句中出现了多个变中都存在的字段,则必须指明此字段所在的表
select employee_id,department_name,employees.department_id
from employees,departments
where employees.department_id = departments.department_id ;
select *
from job_grades ;
#不等值连接
#查询工资在~到~之间的员工姓,工资,等级
select e.last_name,e.salary,jg.grade_level
from employees e,job_grades jg
where e.salary between jg.lowest_sal and jg.highest_sal ;
#查询员工ID员工姓名及其管理者ID姓名,自连接
select e.employee_id '员工ID',e.last_name,e2.employee_id '管理者ID',e2.last_name
from employees e ,employees e2
where e.manager_id = e2.employee_id;
select last_name ,department_name,city
from employees e join departments d
on e.employee_id = d.department_id
join locations l
on d.location_id = l.location_id ;
#左外连接
select last_name,department_name
from employees e left outer join departments d
on e.department_id  = d.department_id ;
#右
select last_name,department_name
from employees e right join departments d
on e.department_id  = d.department_id ;
#满外连接mysql不支持full
select last_name,department_name
from employees e full join departments d
on e.department_id = d.department_id ;
select e.last_name,d.department_id,d.department_name
from employees e left join departments d
on e.department_id = d.department_id ;
select job_id,location_id
from employees e join departments d
on e.department_id = d.department_id
where d.department_id = 90;
select e.last_name,d.department_name,d.location_id,l.city
from employees e left join departments d
on e.department_id = d.department_id
left join locations l
on d.location_id = l.location_id
where e.commission_pct is not null ;
select last_name,job_id,e.department_id,d.department_name
from employees e join departments d
on e.department_id = d.department_id
join locations l
on d.location_id = l.location_id  
where l.city = 'toronto';
select ceil(32.34)
from dual;
select rand()
from dual;
select sin(radians(30)),degrees(asin(1)),tan(radians(45)),degrees(atan(1))  
from dual;
select pow(2,5),power(2,4),exp(2)
from dual;
select ln(exp(2)),log10(10),log2(2)  
from dual;
select concat(e.last_name,' worked for ',e2.last_name) "details"
from employees e join employees e2
on e.manager_id  = e2.employee_id ;
select concat_ws('-','hello','word')
from dual;
#字符串的索引从一开始
select insert ()
事务(Transaction):
也称工作单元,是由一个或多个SQL语句所组成的操作序列,这些SQL语句作为一个完整的工作单元,要么全部执行成功,要么全部执行失败。在数据库中,通过事务来保证数据的一致性
事务处理语言:Transaction Process Language ,简称TPL,主要用来对组成事务的DML语句的操作结果进行确认或取消。确认也就是 使DML操作生效,使用 提交(COMMIT)命令实现;取消也就是 使DML操作失效,使用 回滚(ROLLBACK)命令实现。
通过事务的使用,能防止数据库中出现数据不一致现象。如两个银行账户进行转账,涉及到两条更新操作,这两条更新操作只允许全部成功或失败,否则数据会出现不一致的现象。
原子性(Atomicity)
    事务就像“原子”一样,不可被分割,组成事务的DML操作语句要么全成功,要么全失败,不可能出现部分成功部分失败        的情况。
一致性(Consistency)
    一旦事务完成,不管是成功的,还是失败的,整个系统处于数据一致的状态。
隔离性(Isolation)
    一个事务的执行不会被另一个事务所干扰。比如两个人同时从一个账户从取钱,通过事务的隔离性确保账户余额的正确性。
数据库事务的隔离级别分为四种:(后面为解决的问题,结合下文案例深入理解)
1.读未提交(Read Uncommited)事务1修改的数据被事务2给回滚了
2.读已提交(Read Commited)事务1读到其他事务修改但是没有提交的信息
3.可重复度(Repeatable Read)在事务1进行多次的查询操作的时候,查询的结果不一致的
4.可串行化(Serializable)在同一事务中查询的时候发现多了很多条记录
持久性(Durability)
    也称为永久性,指事务一旦提交,对数据的改变就是永久的,不可以再被回滚。
数据库优化:
1、适度违反范式
2、适当建立索引  index  普通索引 主键索引 唯一索引 组合索引  
            对经常更新的表就避免对其进行过多的索引。
            对经常用于查询的字段应该创建索引。
            数据量小的表最好不要使用索引。
            相同值较多的字段上不要建立索引(比如"性别"字段)。相反的,在不同值较多的字段上可              以建立索引。
3 对表进行水平或垂直划分如果一张表数据过多可以拆分成多张表,或者页可以把一部分字段拆分到另一个表
4 选择合适的数据库引擎InnoDB存储引擎支持外键、支持事务、支持全文检索
Sql语句优化:
    1 尽量使用 批量操作
    2 选择 适当的数据类型
    3 文件、图片等大文件用 文件系统存储,不要使用数据库
    4 使用 连接(丁0IN)来代替子查询
首先,最好是在 相同类型的字段间进行比较的操作,可以避免转型的步骤。
其次,在建有 索引的字段上尽量 不要使用函数进行操作。使用函数后索引将失效。
在搜索字符型字段时,我们有时会使用LIKE关键字和通配符,这种做法虽然简单,但却也是以牺牲系统性能为代价的。
应该注意避免在查询中让MySQL进行自动类型转换,因为转换过程也会使索引变得不起作用。心
5、数据库参数配置优化
-- mysql数据库  DBMS
-- 数据库:是一种专门存储信息和维护信息的容器,严格地说数据库是“按照数据结构来组织、存储和管理信息的仓库”
-- 1. 数据库的英文单词: DataBase 简称 : DB
-- 2. 什么数据库?
#    * 用于存储和管理数据的仓库。
-- 3. 数据库的特点:
--     1. 持久化存储数据的。其实数据库就是一个文件系统
--     2. 方便存储和管理数据
--     3. 使用了统一的方式操作数据库 -- SQL
-- 1.什么是SQL?
--     Structured Query Language:结构化查询语言
--     其实就是定义了操作所有关系型数据库的规则。每一种数据库操作的方式存在不一样的地方,称为“方言”。
    
-- 2.SQL通用语法
--     1. SQL 语句可以单行或多行书写,以分号结尾。
--     2. 可使用空格和缩进来增强语句的可读性。
--     3. MySQL 数据库的 SQL 语句不区分大小写,关键字建议使用大写。
--     4. 3 种注释
#        * 单行注释: -- 注释内容 或 # 注释内容(mysql 特有)
#        * 多行注释: /* 注释 */
    
-- 3. SQL分类
--     1) DDL(Data Definition Language)数据定义语言
--         用来定义数据库对象:数据库,表,列等。关键字:create, drop,alter 等
--     2) DML(Data Manipulation Language)数据操作语言
--         用来对数据库中表的数据进行增删改。关键字:insert, delete, update 等
--     3) DQL(Data Query Language)数据查询语言
--         用来查询数据库中表的记录(数据)。关键字:select, where 等
--     4) DCL(Data Control Language)数据控制语言(了解)
--         用来定义数据库的访问权限和安全级别,及创建用户。关键字:GRANT, REVOKE 等
-- 查询   DQL  选择行  投影列  表连接
-- emp(员工表)hiredate 入职日期 deptno 部门编号 sal 工资 mgr 经理编号 comm 奖金
-- 注意 数据库中的代码统称为:SQL 不区分大小写
-- sql语句中也有关键字要注意
-- 查询表中所有数据
SELECT * FROM emp;
SELECT empno,ename,sal FROM emp;
SELECT empno 员工编号,c,job 职位,sal 工资,deptno 部门 FROM emp;
SELECT ename 员工姓名,sal 工资,sal*1.2 涨薪后
FROM emp;
SELECT ename 员工姓名,sal*1.2*6+sal*6 年薪
FROM emp;
-- 空值是指一种无效的、未赋值、未知的或不可用的值。NULL空值不同于零或者空格。
-- 任何包含空值的算术表达式运算后的结果都为空值NULLo
-- IFNULL(comm,0)
SELECT ename 员工姓名,sal 工资,IFNULL(comm,0) 奖金,(sal*1.2+IFNULL(comm,0))*6+(sal+IFNULL(comm,0))*6 年薪
FROM emp;
-- 消除重复行 DISTINCT
SELECT DISTINCT deptno FROM emp;
-- 查看表结构
DESC emp;
-- 查询10部门的员工
SELECT * FROM emp WHERE deptno = 10;
-- 字符型数据作为被比较的值时,必须用单引号引起来
SELECT * FROM emp WHERE job = 'MANAGER';
-- 比较日期
SELECT * FROM emp WHERE hiredate > '1981-05-01';
-- 练习
SELECT empno 员工编号,job 职位,hiredate 入职日期
FROM emp
WHERE job = 'SALESMAN';
SELECT ename 员工姓名,hiredate 入职日期
FROM emp
WHERE hiredate < '1985-12-31';
SELECT empno 员工编号,ename 员工姓名
FROM emp
WHERE job <> 10;
-- 特殊比较运算符
-- 1.BETWEEN...AND... (范围)
-- 2.IN (集合列表) IN(10,20,30)
-- 3.LIKE  模糊查询
-- 4.IS NULL 是空
-- 练习
SELECT ename 员工姓名,hiredate 入职日期
FROM emp
WHERE hiredate BETWEEN '1982-01-01' AND '1985-12-31';
SELECT ename 员工姓名,sal 工资
FROM emp
WHERE sal BETWEEN 3000 AND 5000;
SELECT ename 员工姓名,deptno 部门编号
FROM emp
WHERE deptno IN (10,20);
SELECT ename 员工姓名,mgr 经理编号
FROM emp
WHERE mgr IN(7902,7566,7788);
-- LIKE  使用LIKE运算符判断要比较的值是否满足部分匹配,也叫模糊查询
-- % :0或任意字符 _ :一个字符  @: @_ 将下划线转成普通字符
SELECT
    *
FROM
    emp
WHERE
    job LIKE 'MAN@_%' ESCAPE '@'
-- 练习
SELECT *
FROM emp
WHERE ename LIKE 'W%'
SELECT *
FROM emp
WHERE ename LIKE '%T_'
SELECT ename 员工姓名,comm 奖金
FROM EMP
WHERE comm IS NULL
-- 逻辑运算符  AND OR NOT
-- 优先级 NOT > AND > OR
-- 练习
SELECT ename 员工姓名,job 职位,sal 工资
FROM emp
WHERE sal > 2000 AND (job = 'MANAGER' OR job = 'SALESMAN')
#job = 'MANAGER' OR 'SALESMAN'
SELECT ename 员工姓名,job 职位,sal 工资
FROM emp
WHERE sal BETWEEN 3000 AND 5000
AND deptno IN (10,20)
SELECT ename 员工姓名,hiredate 入职日期,job 职位
FROM emp
WHERE hiredate BETWEEN '1981-01-01' AND '1981-12-31'
AND job NOT LIKE 'SALES%'
SELECT ename 员工姓名,job 职位,deptno 部门编号
FROM emp
WHERE job IN('SALESMAN','MANAGER')
AND deptno IN(10,20)
AND ename LIKE '%A%'
-- ORDER BY 排序
-- 1.可以按照列名、表达式、列别名、结果集的列序号排序
-- 2.ASC 升序(默认)DESC (降序)
-- 3.ORDER BY 子句必须放在最后
-- .排序规则(以升序为例)
-- ·数字升序排列小值在前,大值在后。即按照数字大小顺序由小到大排列。
-- ·日期升序排列相对较早的日期在前,较晚的日期在后。
-- ·字符升序排列按照字母由小到大的顺序排列。即由A-z排列;中文升序按照字典顺序排列。
-- ·空值在升序排列中排在最前面,在降序排列中排在最后。
-- ·按列名升序排序
-- 按照 结果集号排序
-- 练习
SELECT ename 员工姓名,deptno 部门编号
FROM emp
WHERE deptno IN(20,30)
ORDER BY sal
SELECT ename 员工姓名,deptno 部门编号,sal 工资
FROM emp
WHERE sal BETWEEN 2000 AND 3000
AND deptno <> 10
ORDER BY deptno , sal DESC
SELECT ename 员工姓名,hiredate 入职日期,job 职位
FROM emp
WHERE hiredate BETWEEN '1981-01-01' AND '1983-12-31'
AND (job LIKE 'SALES%' OR job LIKE 'MAN%')
ORDER BY hiredate DESC
-- 作业
SELECT ename 员工姓名,hiredate 入职日期,job 职位
FROM emp
WHERE hiredate > '1982-7-9'
AND job <> 'SALESMAN'
SELECT ename 员工姓名
FROM emp
WHERE ename LIKE '__A%'
SELECT ename 员工姓名,deptno 部门编号
FROM emp
WHERE deptno NOT IN(10,20)
SELECT *
FROM emp
WHERE deptno = 30
ORDER BY sal DESC ,ename
SELECT ename 员工姓名
FROM emp
WHERE mgr IS NULL
SELECT ename 员工姓名,sal 工资,deptno 部门编号
FROM emp
WHERE sal > 4500
AND deptno IN(10,20)
-- 多表连接:什么是连接?
-- 连接是在多个表之间通过一定的连接条件,使表之间发生关联,进而能从多个表之间获取数据。
-- N个表相连接,至少需要N-1个连接条件
-- 表连接的分类:写法:92写法 和99写法(左外连接,右外连接)
#按条件分
#等值连接,非等值连接
#外连接,内连接(和自己本身连接)
-- 查询员工姓名(EMP)、部门名称(DEPT)、工作地点(DEPT)?
-- DEPT deptno 部门编号 dname 部门编号 loc 工作地点
-- 等值连接 先写表链接,再写连接限制条件
SELECT e.ename 员工姓名,d.dname 部门名称 ,d.loc 工作地点
FROM emp e,dept d
WHERE e.deptno = d.deptno
SELECT * FROM dept
SELECT * FROM emp
-- 笛卡尔积:第一个表中所有的行和第二个表中所有的行都发生连接
-- 笛卡尔积条件:连接条件被省略或连接条件是无效的
SELECT e.ename 员工姓名,d.dname 部门编号 ,d.loc 工作地点
FROM emp e,dept d
SELECT e.ename 员工姓名,d.dname 部门编号 ,d.loc 工作地点
FROM emp e,dept d
WHERE e.deptno = e.deptno
SELECT e.ename 员工姓名,d.dname 部门编号 ,d.loc 工作地点
FROM emp e
JOIN dept d ON e.deptno = d.deptno
-- 练习
SELECT e.ename 员工姓名,d.dname 部门编号 ,d.dname 部门名称
FROM emp e,dept d
WHERE e.deptno = d.deptno
SELECT e.ename 员工姓名,d.loc 工作地,e.comm 奖金
FROM emp e,dept d
WHERE e.deptno = d.deptno
AND d.loc = 'CHICAGO'
AND comm IS NOT NULL
SELECT e.ename 员工姓名,d.loc 工作地
FROM emp e,  dept d
WHERE e.deptno = d.deptno
AND e.ename LIKE '%A%'
SELECT * FROM salgrade
-- 非等值连接
#grade 工资等级 losal 最低工资 hisal 最高工资
SELECT e.ename 员工姓名,sal 工资,grade 工资等级
FROM emp e,salgrade s
WHERE e.sal
BETWEEN s.losal AND s.hisal
-- 等值连接与非等值连接
SELECT e.empno 员工编号,e.ename 员工姓名,sal 工资,grade 工资等级,d.loc 工作地点
FROM emp e,salgrade s,dept d
WHERE e.sal
BETWEEN s.losal AND s.hisal
AND e.deptno = d.deptno
SELECT e.empno 员工编号,e.ename 员工姓名,sal 工资,grade 工资等级,d.loc 工作地
FROM emp e,salgrade s,dept d
WHERE e.sal
BETWEEN s.losal AND s.hisal
AND e.deptno = d.deptno
ORDER BY grade
SELECT e.empno 员工编号,e.ename 员工姓名,sal 工资,grade 工资等级,d.loc 工作地
FROM emp e
JOIN salgrade s ON e.sal BETWEEN s.losal AND s.hisal
JOIN dept d ON e.deptno = d.deptno
ORDER BY sal
-- 自连接
SELECT e1.empno 员工编号,e1.ename 员工姓名,e2.ename 经理姓名,e2.empno
FROM emp e1,emp e2,dept d
WHERE e1.mgr = e2.empno
AND e1.deptno = d.deptno
AND d.loc IN ('NEW YORK','CHICAGO')
-- 左外连接:在多表连接时,可以使用外部连接来查看哪些行,按照连接条件没有被匹配上
-- 左外连接以FROM子句中的左边表为基表,该表所有行数据按照连接条件无论是否与右边表能匹配上,都会被显示出来。
SELECT e.ename 员工姓名,d.loc 工作地
FROM emp e
LEFT OUTER JOIN dept d ON e.deptno = d.deptno
-- 练习
SELECT e.ename ,d.dname ,e1.ename
FROM emp e
JOIN dept d ON e.deptno = d.deptno
JOIN emp e1 ON e.mgr = e1.empno
WHERE e.ename = 'SMITH'
-- 外连接
SELECT e.ename 员工姓名,dname 部门名称,sal 工资,grade 工资等级
FROM emp e
JOIN salgrade s ON e.sal BETWEEN s.losal AND s.hisal
JOIN dept d ON e.deptno = d.deptno
WHERE s.grade >= 4
ORDER BY sal
-- 分组查询
#分组函数(聚合函数)返回的结果是一条语句  忽略空值
#MIN() MAX() SUM() AVG() COUNT()计数返回非空行的数量
SELECT MAX(sal),MIN(sal),AVG(sal),SUM(sal),COUNT(empno)
FROM emp
-- 先去重 再计数
SELECT COUNT(DISTINCT deptno) FROM emp
SELECT AVG(comm)  忽略空值
FROM emp
SELECT AVG(IFNULL(comm,0))
FROM emp
SELECT SUM(sal),AVG(sal)
FROM emp
WHERE deptno = 20
SELECT COUNT(*),MAX(sal),MIN(sal)
FROM emp e
JOIN dept d ON e.deptno = d.deptno
WHERE d.loc = 'CHICAGO'
SELECT COUNT(DISTINCT job)
FROM emp
-- 分组语句
-- GROUP BY 子句
-- 在SELECT列表中除了分组函数那些项,所有列都必须包含在GROUP BY子句中。
-- GROUP BY所指定的列并不是必须出现在SELECT列表中。
SELECT AVG(sal),deptno
GROUP BY deptno
SELECT deptno ,SUM(sal),job
FROM emp
GROUP BY deptno,job
-- 练习
SELECT e.deptno,dname,COUNT(empno),MAX(sal),MIN(sal),AVG(sal),SUM(sal)
FROM emp e
JOIN dept d ON e.deptno = d.deptno
GROUP BY e.deptno
SELECT e.deptno,dname,job,COUNT(empno),MAX(sal),MIN(sal),AVG(sal),SUM(sal)
FROM emp e
JOIN dept d ON e.deptno = d.deptno
GROUP BY e.deptno,job
SELECT COUNT(*),m.empno,m.ename
FROM emp e
LEFT JOIN emp m ON e.mgr = m.empno
GROUP BY e.mgr
ORDER BY COUNT(e.mgr)
-- HAVING
-- 分组子句后不允许使用where用having
-- 因为where子句不能比较聚合函数
SELECT MAX(sal),deptno
FROM emp
GROUP BY deptno
HAVING MAX(sal) > 2900
1、通过FROM子句中找到需要查询的表;
2、通过WHERE子句进行非分组函数筛选判断;
3、通过GROUP BY子句完成分组操作;
4、通过HAVING子句完成组函数筛选判断;
5、通过SELECT子句选择显示的列或表达式及组函数;
6、通过ORDER BY子句进行排序操作。
-- 练习
SELECT e.deptno,dname,count(*)
FROM emp e
JOIN dept d ON e.deptno = d.deptno
GROUP BY e.deptno
HAVING count(*)>2
SELECT e.deptno,dname,COUNT(*),AVG(sal)
FROM emp e
JOIN dept d ON e.deptno = d.deptno
GROUP BY e.deptno
HAVING avg(sal) > 2000
AND count(*) > 2
ORDER BY count(*)
-- 子查询
SELECT *
FROM emp
WHERE sal > (SELECT sal FROM emp WHERE ename = 'Jones')
SELECT ename
FROM emp
WHERE sal = (SELECT min(sal) FROM emp)
SELECT ename
FROM emp
HAVING min(sal)
-- 子查询不能有空值
-- 单行子查询:返回一列一行
SELECT ename,job
FROM emp
WHERE sal > (SELECT sal FROM emp WHERE empno = 7876)
AND job = (SELECT job FROM emp WHERE empno = 7369)
SELECT ename,job,sal
FROM emp
HAVING min(sal)
SELECT deptno,min(sal)
FROM emp
GROUP BY deptno
HAVING min(sal)>(SELECT min(sal) FROM emp WHERE deptno = 20)
#查询入职日期最早的员工姓名,入职日期
SELECT ename,hiredate
FROM emp
HAVING min(hiredate)
#查询工资比SMITH工资高并且工作地点在CHICAGO的员工姓名工资,部门名称
SELECT e.ename,e.sal,d.dname
FROM emp e
JOIN dept d ON e.deptno = d.deptno
WHERE sal > (SELECT sal FROM emp WHERE ename = 'SMITH')
AND d.loc = 'CHICAGO'
#查询入职日期比20部门入职日期最早的员工还要早的员工姓名,入职日期
SELECT ename,hiredate
FROM emp
WHERE hiredate < (SELECT min(hiredate) FROM emp WHERE deptno = 20)
--
和多行子查询进行比较时,需要使用多行操作符,多行操作符包括:
IN :集合列表
ANY :表示和子查询的任意一行结果进行比较,有一个满足条件即可。、
    >ANY: 大于最小
    <ANY:小于最大
    =ANY:IN
ALL :表示和子查询的所有行结果进行比较,每一行必须都满足条件。
    >ALL: 大于所有
    <ALL: 小于所有
    =ALL:
-- 不是经理
SELECT ename
FROM emp
WHERE empno NOT IN (SELECT mgr FROM emp WHERE mgr IS NOT NULL)
-- 查询比自己部门平均工资高的员工姓名,工资,部门编号,部门平均工资
SELECT e.ename,e.sal,e.deptno,a.asl
FROM emp e
JOIN (SELECT avg(sal) asl,deptno FROM emp GROUP BY deptno) a
ON e.deptno = a.deptno
WHERE e.sal > a.asl
-- 限制记录行数
LIMIT
x:开始索引  y:数据条目数  n:页数
x = (n-1) * y
SELECT * FROM emp LIMIT x,y
-------------------------------------------------------------- 数据库中的表
表概念:表是数据库中最重要的逻辑对象,是存储数据的主要对象
-- MySQL 数据类型:
数值类型:INT FLOAT DOUBLE BIGINT
INT(4)四位整数
DOUBLE(7,2)七位数,小数点后保留两位,小数点占两位
日期类型:
DATE
DATETIME带时分秒
TIMESTAMP 时间戳 高精度 TIMESTAMP(3)毫秒 TIMESTAMP(6)微秒
插入数据更新数据是使用时间戳记录当前的时间
字符串:
char 定长
varchar 可变
BLOB 二进制大对象  如存储电影  转成二进制  存入blob
tixt 大文本
ENUM('',''...) 枚举  多选一
-- 创建表
-- 主键约束 PRIMARY KEY 唯一标识
CREATE TABLE Student(
  stu_id int(4) PRIMARY KEY,
    stu_name VARCHAR(10),
    stu_sex enum('男','女'),
    stu_age INT(2) DEFAULT 18,-- 默认
    stu_birthday DATE,
    stu_school VARCHAR(20),
    stu_subjects INT(4) -- 外键
)
CREATE TABLE subjects(
  stu_subjects INT(4) PRIMARY KEY,
    sub_name VARCHAR(20) UNIQUE, -- 唯一
    sub_loc VARCHAR(10) NOT NULL -- 非空
    
)
-- 在创建表时就加入外键
-- 先创建关联子表
-- 在主表加外键
CREATE TABLE Student(
  
    stu_subjects INT(4) -- 外键
    FOREIGN KEY (stu_subjects) REFERENCES subjects(stu_subjects)
)
-- 外部添加外键约束
ALTER TABLE student ADD CONSTRAINT FK_student_subjects FOREIGN KEY student(stu_subjects) REFERENCES subjects(stu_subjects)
ADD CONSTRAINT -- 添加约束
REFERENCES -- 关联
-- 销毁表
DROP TABLE Student
-- 查看表结构
DESC student
-- 约束
自增长:
auto-increment
非空约束:
NOT NULL
唯一约束:指定列或者列的组合的所有行数据必须唯一
UNIQUE
主键约束: 表的每行的唯一性标识,指定列或者列的组合的所有行数据必须唯一
PRIMARY KEY
检查约束: MySQL不支持
CHECK
默认约束:
DEFAULT
外键约束:参照表只可以是唯一键 或 主键
FOREIGN KEY
--------------------------------------------------------------
-- 练习
CREATE TABLE faculties(
  f_id INT(4) PRIMARY KEY,
    f_name VARCHAR(10) UNIQUE,
    f_head VARCHAR(10) NOT NULL,
    f_loc VARCHAR(10) DEFAULT '浑南区'
)
CREATE TABLE class(
  c_id INT(4) PRIMARY KEY,
    c_name VARCHAR(10) UNIQUE,
    f_id INT(4)
)
ALTER TABLE class ADD CONSTRAINT FK_faculties_class FOREIGN
KEY (f_id) REFERENCES faculties(f_id)
CREATE TABLE stu(
    s_id CHAR(10) PRIMARY KEY,
    s_name VARCHAR(20) NOT NULL,
    s_sex CHAR(2),
    s_birthday DATE,
    s_class INT(4)
)
DESC faculties
DESC class
DROP TABLE faculties
DROP TABLE class
DROP TABLE stu
-- 复制表
-- 不包括数据仅为结构
CREATE TABLE 新表名 LIKE 源表
-- 带数据
CREATE TABLE 新表名 SELECT * FROM 源表
-- 重命名
RENAME TABLE 旧表名 TO 新表名
-- 等同于
ALTER TABLE 旧表名 RENAME 新表名
-- 加一列
ALTER TABLE 表名 ADD 列名 数据类型 NOT NULL
-- 改一列
ALTER TABLE 表名 MODIFY 列名 数据类型 NOT NULL
-- 删列
ALTER TABLE 表名 DROP COLUMN 列名
-- 练习
ALTER TABLE stu ADD gender CHAR(2) DEFAULT '男'
ALTER TABLE stu MODIFY gender char(4)
ALTER TABLE stu MODIFY gender CHAR(4) DEFAULT '女'
ALTER TABLE stu DROP gender
-- 约束
格式: alter table表名add constraint 约束名 约束类型(字段名)
ALTER TABLE car ADD CONSTRAINT uc UNIQUE (cname)
CREATE TABLE car(
    id INT(10) PRIMARY KEY,
    price DOUBLE(5,2),
    color VARCHAR(6)
)
ALTER TABLE car ADD cname VARCHAR(10)
ALTER TABLE car DROP price
DROP TABLE car
-- 查看约束
SHOW INDEX IN 表名
-- 删除唯一约束
ALTER TABLE 表名 DROP INDEX 约束名
-- 删除主键/外键约束
ALTER TABLE 表名 DROP PRIMARY KEY 约束名
ALTER TABLE 表名 DROP FOREIGN KEY 约束名
-- 插入数据
INSERT INTO car(id,color,cname) VALUE (1001,'黑色','宝马')
INSERT INTO car VALUE (1002,'蓝色','奔驰')
-- 主键自增 auto-increment
alter table 表名 change 名 列名 int not null auto_increment
ALTER TABLE 表名 auto_increment=10 (初始值)
SET auto_increment_increment=10  (每次增长)
-- 查询
SHOW VARIABLES LIKE '%increment%'
-- 修改数据
UPDATE 表名 SET 列名1 = 值 1,列2 = 值2 WHERE 条件
#WHERE子句用来限定修改哪些行。SET子句用来限定修改哪些列。
#WHERE子句中的更新条件是一个逻辑表达式通常需要使用到关系运算符
#和逻辑运算符,返回True或者False。
UPDATE emp SET sal = sal-200 WHERE ename = 'SMITH'
UPDATE emp SET deptno = 20 WHERE empno = 7788
UPDATE emp SET DATE_ADD(hiredate,interval 3 day)
WHERE deptno = 20 AND hiredate > '1982-12-31'
UPDATE emp SET comm = 0 WHERE comm IS NULL
UPDATE emp
SET sal=500+sal
WHERE deptno IN
    (SELECT deptno FROM dept WHERE loc IN ('NEW YORK','CHICAGO'))
UPDATE emp e ,dept d
SET sal=500+sal
WHERE e.deptno = d.deptno AND d.loc IN ('NEW YORK','CHICAGO')
ROLLBACK
-- 为指定日期加天数
DATE_ADD(hiredate,interval 3 day)
-- 删除数据delete  销毁表drop删除表结构释放空间
DELETE FROM 表名 [WHERE 条件]
DELETE FROM emp WHERE mgr = 7566
DELETE FROM emp WHERE deptno =
    (SELECT deptno FROM dept WHERE loc = 'new york')
    
DELETE FROM emp GROUP BY deptno HAVING sal > avg(sal)
-- DELETE FROM emp WHERE empno IN  
-- (SELECT empno FROM
--     (SELECT empno FROM
--         (SELECT avg(sal) avg,deptno FROM emp WHERE deptno IS NOT          NULL GROUP BY deptno) a ,emp e
--     WHERE a.deptno = e.deptno
--     AND sal > avg) eno)
-- 截断表 介于delete和drop之间删除数据不删表结构释放空间
TRUNCATE TABLEtable;
TRUNCATE TABL.Eemp ;
TRUNCATE和DELETE区别
-TRUNCATE是DDL,只能删除表中所有记录,释放存储空间,使用ROLLBACK不可以回滚。
- DELETE是DML,可以删除指定记录,不释放存储空间,使用ROLLBACK可以回滚。
-- 视图与索引
视图:视图是逻辑上来自一个或多个表的数据集合。视图不是表
视图:view
表:TABLE
为什么使用视图
-限制其它用户对数据库表的访问,因为视图可以有选择性的显示数据库表的一部分
-容易实现复杂的查询;
-对于相同的数据可以产生不同的视图;
CREATE VIEW v_emp10
AS SELECT empno,ename,job FROM emp WHERE deptno = 10
DESC v_emp10                    
                                                                    
SELECT * FROM v_emp10                        
                    
-- OR REPLACE
OR REPLACE:如果所创建的视图已经存在,该选项表示修改原视图的定义
CREATE OR REPLACE VIEW v_emp10
AS SELECT empno,ename,sal,job FROM emp WHERE deptno = 10
DESC v_emp10                
--
注意:在视图(来自于一张表的)上删除视图数据主表的数据也会删除
视图全删除―主表不会有影响
册除视图不会影响在主表
删除视图里面的数据会影响到源表
DROP VIEW 名
-- 索引:提高数据库查询效率 INDEX
类型:普通索引、唯一性索引、全文索引
-- 索引是一种特殊的数据库结构,可以用来快速查询数据库表中的特定记录
-- 索引是提高数据库性能的重要方式。MySQL中,所有的数据类型都可以被索引
-- 创建索引的方式
创建表的时候创建索引
在已经存在的表上创建索引
使用ALTER TABLE语句来创建索引
-- 普通索引、唯一性索引、全文索引
Create table table_1(
Id int(4),
Name varchar(20),
sex boolean,
Index(id)
)
Create table table_2(
Id int PRIMARY KEY,
Name varchar( 20),
Unique index index2_id(id asc)
);
Create table table_3(
Id int,
Info varchar(20),
Fulltext index index3_info(info)
)engine=myisam;
engine=myisam 设置数据库引擎
-- 2.在已经存在的表上创建索引
CREATE[ UNIQUE / FULLTEXT / SPATIAL ] INDEX索引名
ON 表名 (属性名[(长度)][ ASC | DESC] );
-- 普通索引
CREATE INDEX uk_name on table_1 (name(20))
-- 唯一索引
CREATE UNIQUE INDEX uk_name on table_1 (name(20))
-- 3.ALTER TABLE
ALTER TABLE 表名ADD[ UNIQUE |FULLTEXT | SPATIAL ]INDEX
索引名(属性名[(长度)][ AsC ( DESC])
ALTER TABLE table_2 ADD UNIQUE INDEX uk_name (Name (20))
-- 删除索引
DROP INDEX 索引名 ON 表名
DROP INDEX uk_name ON table_2
#索引的设计原则
-- 选择惟一性索引
-- 为经常需要排序、分组和联合操作的字段建立索引
-- 为常作为查询条件的字段建立索引
-- 限制索引的数目
-- 尽量使用数据量少的索引-尽量使用前缀来索引
-- 删除不再使用或者很少使用的索引
-- 数据库小结
    
---------------------------------------------------------------    
-- 练习
CREATE OR REPLACE VIEW v_emps
AS SELECT empno 员工编号,ename 员工姓名,sal 工资 FROM emp
WHERE sal BETWEEN 2000 AND 5000 AND ename LIKE '%a%'
SELECT * FROM V_emps
    
CREATE OR REPLACE VIEW v_dsal
AS SELECT dname 部门名称,min(sal) 最低工资,max(sal) 最高工资,avg(sal) 平均工资
FROM emp e ,dept d
WHERE e.deptno = d.deptno
GROUP BY e.deptno
SELECT * FROM v_dsal
CREATE VIEW V_1 AS
SELECT empno,ename,e.deptno,hiredate
FROM emp e ,dept d
WHERE e.deptno = d.deptno
AND d.loc IN ('new york','chicago')
    
CREATE OR REPLACE VIEW V_2 AS
SELECT e.deptno,dname,min(sal) m
FROM emp e ,dept d
WHERE e.deptno = d.deptno
GROUP BY e.deptno
SELECT e.ename,v.dname
FROM emp e,v_2 v
WHERE e.deptno = v.deptno
AND e.sal = v.m
    
-- 练习                                                            
ALTER TABLE salgrade auto_increment=10
SET auto_increment_increment=10
SHOW VARIABLES LIKE '%increment%'
INSERT INTO dept VALUE (50,'HR','SY')
INSERT INTO dept(deptno,dname) VALUE (60,'MARKET')
SELECT * FROM dept
INSERT INTO emp(empno,ename,job,mgr,hiredate,sal) VALUE (8888,'BOB','CLERK',7788,'1985-03-03',3000)
SELECT * FROM emp
CREATE TABLE Manager LIKE emp
INSERT INTO manager
    SELECT *
    FROM emp
    WHERE job = 'MANAGER'
SELECT * FROM manager
CREATE TABLE emp_back
    SELECT *
    FROM emp
    WHERE hiredate < '1982-01-01'
SELECT * FROM emp_back
DROP TABLE emp_back
-- 作业
1.显示入职日期在80年5月1日之后的员工姓名,部门名称,入职日期
SELECT ename 员工姓名,hiredate 入职日期,job 职位
FROM emp
WHERE hiredate > '1980-05-01'
2.使用左连接,查询每个员工的姓名,经理姓名,没有经理的King也要显示出来。
SELECT e.ename 员工姓名,m.ename 经理姓名
FROM emp e
LEFT JOIN emp m ON e.mgr = m.empno
3.使用右连接,查询每个员工的姓名,经理姓名,没有经理的King也要显示出来。
SELECT e.ename 员工姓名,m.ename 经理姓名
FROM emp e
RIGHT JOIN emp m ON e.mgr = m.empno
4. 显示员工KING和FORD管理的员工姓名及其经理姓名。
SELECT e.ename 员工姓名,m.ename 经理姓名
FROM emp e
LEFT JOIN emp m ON e.mgr = m.empno
WHERE e.ename = 'KING'
OR m.ename = 'KING'
OR e.ename = 'FORD'
OR m.ename = 'FORD'
5. 显示员工姓名,参加工作时间,经理名,参加工作时间,要求参加时间比经理早。
SELECT e.ename 员工姓名,e.hiredate 入职日期,m.ename 经理姓名,md.hiredate 入职日期
FROM emp e
LEFT JOIN emp m ON e.mgr = m.empno
JOIN emp md ON e.mgr = md.empno
WHERE e.hiredate < md.hiredate
6. 查询部门平均工资在2500元以上的部门名称及平均工资。
SELECT dname 部门名称,avg(sal) 平均工资
FROM emp e
JOIN dept d ON e.deptno = d.deptno
GROUP BY e.deptno
HAVING avg(sal) > 2500
7. 查询部门人数在2人以上的部门名称、最低工资、最高工资。
SELECT dname 部门名称,MAX(sal) 最高工资,MIN(sal) 最低工资
FROM emp e
JOIN dept d ON e.deptno = d.deptno
GROUP BY e.deptno
HAVING COUNT(*)>2
8. 显示经理号码和经理姓名,这个经理所管理员工的最低工资,没有经理的KING也要显示,不包括最低工资小于3000的,按最低工资由高到低排序
SELECT m.empno 经理号码,m.ename 经理姓名,MIN(e.sal) 最低工资
FROM emp e
LEFT JOIN emp m ON e.mgr = m.empno
GROUP BY e.mgr
HAVING MIN(e.sal) > 3000
ORDER BY MIN(e.sal) DESC
-- 练习
SELECT DISTINCT ename,sal
FROM emp
WHERE empno IN (SELECT mgr FROM emp)
SELECT ename,job,sal
FROM emp
WHERE deptno <> 10
AND sal > ANY (SELECT sal FROM emp WHERE deptno = 10)
SELECT empno,ename,job,sal
FROM emp                                
WHERE deptno <> 20
AND sal > ALL (SELECT sal FROM emp WHERE deptno = 20)
SELECT ename,hiredate
FROM emp
WHERE hiredate >ANY
(SELECT hiredate FROM emp WHERE deptno = 10)
AND deptno <> 10
SELECT ename,hiredate
FROM emp
WHERE hiredate >ALL
(SELECT hiredate FROM emp WHERE deptno = 10)
AND deptno <>10
SELECT ename,job
FROM emp
WHERE job IN
(SELECT job FROM emp WHERE deptno = 10)
AND deptno <> 10
-- 作业
查询部门平均工资在2500元以上的部门名称及平均工资。
SELECT dname,avg(sal)
FROM emp e
JOIN dept d ON e.deptno = d.deptno
GROUP BY e.deptno
HAVING avg(sal) > 2500
查询员工岗位中不是以“SA”开头并且平均工资在2500元以上的岗位及平均工资,并按平均工资降序排序。
SELECT job,avg(sal)
FROM emp
WHERE job NOT LIKE 'SA%'
GROUP BY job
HAVING avg(sal) > 2500
ORDER BY avg(sal) DESC
查询部门人数在2人以上的部门名称、最低工资、最高工资。
SELECT dname,min(sal),max(sal)
FROM emp e
JOIN dept d ON e.deptno = d.deptno
GROUP BY d.dname
HAVING count(*) > 2
查询岗位不为SALESMAN,工资和大于等于2500的岗位及每种岗位的工资和。
SELECT job, sum(sal)
FROM emp
WHERE job <> 'SALESMAN'
GROUP BY job
HAVING sum(sal) > 2500
显示经理号码和经理姓名,这个经理所管理员工的最低工资,没有经理的KING也要显示,不包括最低工资小于3000的,按最低工资由高到低排序
SELECT e.ename,m.ename 经理,m.empno,min(e.sal)
FROM emp e
LEFT JOIN emp m ON e.mgr = m.empno
GROUP BY e.mgr
HAVING min(e.sal) > 3000
ORDER BY min(e.sal) DESC
查询工资高于编号为7782的员工工资,并且和7369号员工从事相同工作的员工的编号、姓名及工资。
SELECT empno,ename,sal
FROM emp
WHERE sal > (SELECT sal FROM emp WHERE empno = '7782')
AND job = (SELECT job FROM emp WHERE empno = '7369')
查询工资最高的员工姓名和工资。
SELECT ename,sal
FROM emp
WHERE sal = (SELECT max(sal) FROM emp)
查询部门最低工资高于10号部门最低工资的部门的编号、名称及部门最低工资。
SELECT d.deptno,dname,min(e.sal)
FROM emp e
JOIN dept d ON e.deptno = d.deptno
GROUP BY e.deptno
HAVING min(e.sal) > (SELECT min(sal) FROM emp WHERE deptno = 10)
查询员工工资为其部门最低工资的员工的编号和姓名及工资。
SELECT empno,ename,sal
FROM emp
WHERE sal IN (SELECT min(sal) FROM emp GROUP BY deptno)
显示经理是KING的员工姓名,工资。
SELECT ename,sal
FROM emp
WHERE mgr IN (SELECT empno FROM emp WHERE ename = 'KING')
显示比员工SMITH参加工作时间晚的员工姓名,工资,参加工作时间。
SELECT ename,sal,hiredate
FROM emp
WHERE hiredate > (SELECT hiredate FROM emp WHERE ename = 'SMITH')
创建与emp表结构相同的表empl,并将其部门编号为前30号的员工信息复制到empl表。
CREATE TABLE emp1 SELECT * FROM emp WHERE deptno = 30
DROP TABLE emp1
1. 求部门中薪水最高的人
SELECT *
FROM emp
WHERE sal IN (SELECT max(sal) FROM emp GROUP BY deptno)
2. 查询所有员工中工资排在5~10名之间的员工信息
SELECT *
FROM (SELECT * FROM emp ORDER BY sal DESC) sal
LIMIT 4,6
3. 统计每个部门中各个工种的人数与平均工资。
SELECT count(job),avg(sal),deptno
FROM emp
GROUP BY deptno,job
4. 查询30号部门中工资排序前3名的员工信息
SELECT *
FROM (SELECT * FROM emp WHERE deptno = 30 ORDER BY sal DESC) sal
LIMIT 0,3
5. 查询人数最多的部门信息
SELECT deptno,dname,loc
FROM dept
WHERE deptno =
(SELECT d.deptno
FROM
     (SELECT COUNT(*) cou,deptno
        FROM emp
        GROUP BY deptno
        HAVING cou =
         (SELECT max(c.cou)
            FROM
                (SELECT count(*) cou,deptno
                 FROM emp
                 GROUP BY deptno) c) ) d)
SELECT deptno,dname,loc
FROM dept
WHERE deptno =
(SELECT d.deptno
FROM
     (SELECT COUNT(*) cou,deptno
        FROM emp
        GROUP BY deptno
        HAVING cou >= ALL (SELECT count(*) FROM emp GROUP BY deptno) ) d)
创建视图v_emp_20,包含20号部门的员工编号,姓名,年薪列(年薪=12*(工资+奖金)
CREATE VIEW v_emp_20 AS(
    SELECT empno,ename,(sal+IFNULL(COMM,0))*12 nsal
    FROM emp
    WHERE deptno = 20
)
从视图v_emp_20中查询年薪大于1万元员工的信息;
SELECT * FROM emp
WHERE empno IN (
SELECT empno FROM v_emp_20 WHERE nsal > 10000)
请为工资大于2000的员工创建视图,要求显示员工的部门信息,职位信息,工作地点;
CREATE OR REPLACE VIEW v_emp_e AS
SELECT ename,e.deptno,d.dname,d.loc,job
FROM emp e ,dept d
WHERE e.deptno = d.deptno
AND sal > 2000
create table student ( -- 学生表
    xh char (4),-- 学号
    xm varchar (10),-- 姓名
    sex char(2),-- 性别
    birthday date,-- 出生日期
    sal double(7,2),-- 奖学金
    studentcid int(2) -- 学生班级号
)
Create table class ( -- 班级表
    classid int (2),-- 班级编号
    cname varchar(20),-- 班级名称
    ccount int (3)-- 班级人数
)
-- 2.基于上述学生表和班级表,完成如下问题
-- (1)添加三个班级信息为:
-- 1,JAVA1班,null
-- 2,JAVA2班,null
-- 3,JAVA3班,null
INSERT INTO class VALUE
(1,'JAVA1班',NULL)
INSERT INTO class VALUE
(2,'JAVA2班',NULL),
(3,'JAVA3班',NULL)
-- (2)添加学生信息如下:‘A001’,‘张三’,‘男’,‘01-5月一05’,100,1
INSERT INTO student VALUE ('A001','张三','男','01-5-05',100,1)
-- (3)添加学生信息如下:'AO02','MIKE','男','1905-05-06',10
INSERT INTO student (xh,xm,sex,birthday,sal)
VALUE ('A002','MIKE','男','1905-05-06',10)
-- (4)插入部分学生信息:'A003' , 'JOHN','女’
INSERT INTO student (xh,xm,sex)
VALUE ('A003','JOHN','女')
-- (5)将A001学生性别修改为'女‘
UPDATE student SET sex = '女' WHERE xh = 'A001'
-- (6)将A001学生信息修改如下:性别为男,生日设置为1980-04-01
UPDATE student SET sex = '男',birthday = '1980-04-01' WHERE xh = 'A001'
-- (7)将生日为空的学生班级修改为Java3班
UPDATE student SET studentcid = 3 WHERE birthday IS NULL
-- (8)请使用一条SQL语句,使用子查询,更新班级表中每个班级的人数字段
UPDATE class SET ccount =
(SELECT count(*) FROM student WHERE studentcid = 1)
WHERE cname = 'JAVA1班'
UPDATE class a SET a.ccount = (SELECT c.cou FROM
(SELECT count(*) cou,studentcid FROM student WHERE studentcid in (SELECT classid FROM class) GROUP BY studentcid) c
WHERE a.classid=c.studentcid)
-- -------------------------------------------------------------------------------
CREATE TABLE copy_emp(
    empno int(4),
    ename VARCHAR(20),
    hiredate date,
    deptno int(2),
    sal double(8,2)
)
-- 4.在第三题表的基础上,完成下列问题
-- (1)在表cop ..emp.中插入数据,要求sal字段插入空值,部门号50,参加工作时间为2000年1月1日,其他字段随意
INSERT INTO copy_emp VALUE (1122,'HUILK','2000-01-01',50,NULL)
-- (2)在表copy. .emp.中插入数据,要求把emp表中部门号为10号部门的员工信息插入
INSERT INTO copy_emp SELECT empno,ename,hiredate,deptno,sal FROM emp WHERE deptno = 10
-- (3)修改cop. .emp表中数据,要求10号部门所有员工涨20%的工资
UPDATE copy_emp SET sal = sal*1.2 WHERE deptno = 10
-- (4)修改copy. emp表中sal为空的记录,工资修改为平均工资
UPDATE copy_emp SET sal = (SELECT a.avg FROM (SELECT avg(sal) avg FROM copy_emp) a) WHERE sal IS NULL
-- (5)把工资为平均工资的员工,工资修改为空
UPDATE copy_emp SET sal = NULL WHERE sal = (SELECT a.avg FROM (SELECT avg(sal) avg FROM copy_emp) a)

猜你喜欢

转载自blog.csdn.net/weixin_53031149/article/details/127473852