zoukankan      html  css  js  c++  java
  • MySQL练习与小结

    当你专注一件事的时候,时间总是过得很快!

    • foreign key 练习
    -- 切换数据库
    use stumgr
    -- 删除班级表
    drop table t_class1
    -- 创建一个班级表
    create table t_class1 (
        cno int auto_increment not null,
        cname varchar (12) not null,
        room int (4),
        primary key (cno)
    );
    -- 查看班级表
    desc t_class1
    -- 添加班级数据
    insert into t_class1 values (null,'Javay1班',501),(null,'Javay2班',502),(null,'大数据1班',401);
    -- 查看班级表信息
    select * from t_class1
    -- 清空班级表数据
    truncate table t_class1
    -- 删除学生表
    drop table t_student1
    -- 创建学生表
    create table t_student1 (
        sno int primary key auto_increment,
        name varchar (20),
        sex char (1) default '',
        age int,
        classno int,
        constraint fk_t_student1_classno foreign key (classno) references t_class1 (cno)
    );
    -- 查看学生表
    desc t_student1
    -- 添加学生表数据
    insert into t_student1 values (null,'张三','',22,1);
    insert into t_student1 values (null,'李思','',23,3);
    insert into t_student1 values (null,'王武','',22,3);
    insert into t_student1 (name,age,classno) values ('赵六',21,2),('孙琦',21,1);
    -- 查看学生表数据
    select * from t_student1
    -- 清空学生表数据
    truncate t_student1
    • 单行函数练习
    -- 单行函数
    select * from emp
    select lower(ename) from emp
    select upper(ename) from emp
    select ename from emp
    select ename,lower(ename) from emp 
    select ename,lower(ename),upper(ename) from emp
    select ename,lower(upper(ename)) from emp
    -- 使用函数并没有更改数据库中的数据值,只是简化了查询的代码量
    select sal from emp
    select min(sal),max(sal),sum(sal),avg(sal),count(sal) from emp
    -- 函数的分类
    -- 单行函数 即对(多行)每一条记录进行操作,分别产生一条记录
    -- lower(ename)、upper(name)
    -- 多行函数 对(多行)每一条记录进行操作,结果只产生一条记录
    -- max(sal)、min(sal)、sum(sal)、avg(sal)、count(sal)
    -- 区分单行函数和多行函数
    -- 方法1、按照定义区分
    -- 方法2、除了多行函数(常用的有5个),都是单行函数
    -- 字符函数
    select * from emp where length(ename) = 6
    select ename from emp where length(ename) = 6
    select ename,sal from emp where length(ename) = 6
    select ename,lower(ename),upper(ename) from emp 
    select empno,ename,job,substring(ename,1,3) subname from emp -- 截取字符串 从第一位到第三位 显示职员信息(工号,姓名,岗位)
    select empno,ename,job,replace(job,"CLERK",'店员') from emp where job = 'clerk'
    select empno,ename,job,replace(job,'MANAGER','经理') from emp where job = "MANAGER"
    select job from emp where job = 'manager'
    -- select job where job = 'manager' from emp -- 错误的写法
    select empno,ename,job,replace(job,"MANAGER","经理") from emp where job = 'manager'
    select empno,ename,job,replace(job,'manager',"经理") from emp where job = "MANAGER" -- replace()括号中的职位名必须和表格中一样,不然显示不出后面的汉字
    -- 数值函数
    select 
    abs(-5), -- 取绝对值
    ceil(3.2), -- 向上取整
    floor(3.2), -- 向下取整
    round(3.4),
    round(3.5), -- 四舍五入
    mod(10,3),
    mod(10,5), -- 取模 相当于取余
    pi(), -- 圆周率
    sqrt(25), -- 开平方
    pow(2,5),
    pow(5,2) -- 幂运算
    select rand(),rand(),rand() -- 返回0~1之间的随机数
    select truncate(3.1415926,3) -- truncate(num,n)返回num舍弃小数点后第n位后的数值
    -- 日期函数
    select now(),sysdate(),sleep(3),sysdate(),now()
    select now(),curdate(),curtime()
    -- 流程函数
    select ename,deptno,sal,if(sal >= 3000,"high","low") from emp 
    select ename,deptno,sal,if(sal >= 3000,'高收入层','低收入层') from emp order by sal 
    select ename,deptno,job,sal*12+comm year_income from emp -- 算上补贴的年收入,补贴(comm)为null无法算出年收入
    select ename,deptno,job,sal*12+ifnull(comm,0) year_income from emp -- 加上ifnull(comm,0)可以把补贴为null的置为0,从而得出年收入
    -- ifnull(comm,0) 即 if comm is null then comm = 0
    select nullif(1,1),nullif(1,2),nullif(2,1),nullif(2,2) -- if 1 == 2 then null else 1
    select ename,deptno,sal,case when sal >= 3000 then '高收入' else "低收入" end sal_level from emp 
    select ename,deptno,sal,
    case when sal >= 3000
    then 'high'
    else case when sal >= 2000
    then 'mid'
    else 'low'
    end
    end
    from emp
    -- 其他函数
    select database(),user(),version(),password('zhangsan'),inet_aton('192.168.10.1'),inet_ntoa(3232238081)
    -- mysql 提供了一个名为dual的虚拟表 默认的from dual是可以省略的
    • 单表查询练习
    -- where 子句练习
    select * from emp -- 先查看下员工表信息
    select * from emp where empno = 7566 -- 查询工号为7566的职员信息
    select * from emp where sal > 3000 -- 查看薪水大于3000的职员信息
    select * from emp where job = 'MANAGER'
    select * from emp where JOB = 'manager' -- mysql 中默认不去分大小写
    -- 加上区分大小写的条件 即在查询的字段名前加上binary
    select * from emp where binary job = 'manager'
    select * from emp where job != 'manager'
    select * from emp where job > 'manager' -- 字符串也可以大于小于
    select * from emp where job <> "manager"
    select * from emp where hiredate < '1981-12-23'
    -- and 逻辑运算符
    select * from emp 
    select * from emp where sal <= 3000 and sal >= 1200
    select * from emp where sal between 1200 and 3000 -- between 表示的意思是闭区间
    select * from emp where sal not between 3000 and 1200
    select * from emp where sal <= 3000 && sal >= 1200 -- &&等同于and
    -- or 逻辑运算符
    select * from emp where deptno = 30 or 10 -- 不能这样表述
    select * from emp where deptno = 30 or deptno = 10 -- 查询部门编号为30或10的
    select * from emp where deptno = 30 || deptno = 10 -- ||等同于or
    select * from emp where deptno in (30,10)
    select * from emp where deptno in (10,30)
    -- 模糊匹配
    -- 姓名中带K的 %代表任意多个字符
    select * from emp 
    select * from emp where ename = '%K%' -- 不能使用等号 而是要用单词 like
    select * from emp where ename like '%k%' -- K 不区分大小写
    -- 加上binary就是区分大小写
    select * from emp where binary ename like '%K%'
    select * from emp where binary ename like '%k%'
    select * from emp where binary ename not like '%k%'
    select * from emp where binary ename not like '%K%'
    -- 姓名的第二个字母是L _单个下划线代表任意一个字符 第几个字符要加几个_
    select * from emp where ename like '__m%' -- 名字中第二个字母是m的职员信息
    select * from emp where ename like '_M%' -- 名字中第一个字母是m的职员信息
    select * from emp where binary ename like '_m%' -- 区分大小写 名字中第一字母是小写m的职员信息
    select * from emp where binary ename like '_M%' -- 名字中第一个字母是大写M的职员信息
    -- is null
    select * from emp where comm = 0 -- 不是is null的用法
    select * from emp where comm is null -- 查看comm是null的职员信息,comm是null和comm = 0 代表的含义是不同的
    select * from emp where comm is not null -- is 后加 not 是正确的用法 not加在is前不符合语法要求
    -- select * from emp where comm not is null
    select * from emp where comm != 0 -- 不包括comm为null的数据
    -- 小括号 优先级高
    select * from emp where job = 'salesman' or "CLERK" and sal >= 1280 -- and运算符的优先级比or高 不包括工资大于1280的clerk
    select * from emp where (job = "salesman" or job = "clerk") and sal >= 1280
    select * from emp where job = 'SALESMAN' or (job = 'CLERK' and sal >1280)
    • 表单查询多行函数
    -- 多行函数
    select max(sal),min(sal),sum(sal),count(sal),avg(sal) from emp
    select
    max(comm),min(comm),sum(comm),avg(comm),count(comm) 
    from emp
    select * from emp 
    select 
    max(ename),min(ename),sum(ename),avg(ename),count(ename) 
    from emp
    -- 统计有几个员工
    select
    empno,count(1)
    from emp
    select count(comm) from emp -- 不能通过领补贴的人来统计
    -- 统计有几个部门
    select deptno from dept
    select count(distinct deptno) from emp -- 部门40并未出现在emp表中,所以此语句输出的部门个数是3
    select count(deptno) from dept
    -- 对任意一张表,统计有几条记录
    select count(*) from emp
    select count(*) from dept
    select empno from emp -- 可以通过主键统计
    select 1 from emp
    select count(1) from emp -- 统计表的记录个数建议用此方法,比count(*)效率高
    -- 统计有几个岗位
    select count(distinct job) from emp
    -- 多行函数会自动排除null值
    -- max(),min(),count()适用于所有数据类型
    -- sum()avg()仅限于数值类型(整点 浮点)
    -- 多行函数会更多地用在分组查询中 group by
    • 多表查询练习
    -- SQL99多表连接查询
    -- 查询员工的编号、姓名和部门编号
    select * from emp
    select empno,ename,deptno from emp
    -- 查询员工的编号、姓名和部门编号、部门的名称
    -- 交叉连接 使用关键字join
    select * from dept
    select * from emp
    select *
    from emp
    cross join dept
    select *
    from dept
    cross join emp -- 左和右的区别 左连接 右连接
    -- 自然连接
    select *
    from emp
    natural join dept
    -- 使用关键字natural 会自动按照所有的同名列进行匹配,并且同名列只显示一次
    -- 优点是:简单
    select empno,ename,deptno,dname
    from emp
    natural join dept
    -- 缺点:没有指定各字段属于哪个表,执行时需要进行判断,效率低
    -- 解决:给各个字段指定表的名字
    select emp.empno,emp.ename,deptno,dept.dname -- 自然连接中同名列不能使用表名前缀
    from emp 
    natural join dept
    -- 缺点:表名如果很长,字段多的时候,SQL语句就会显得复杂
    -- 解决:使用别名
    select e.empno,e.ename,deptno,d.dname
    from emp e
    natural join dept d
    -- using 子句
    -- 自然连接的缺点:会自动按照“所有的”同名列进行匹配,如果希望按照某一个同名列进行匹配,自然连接无能为力
    -- 解决:使用using子句
    select * 
    from emp e
    join dept d
    using(deptno) -- e.deptno = d.deptno
    select e.empno,e.ename,deptno,d.dname
    from emp e
    join dept d
    using(deptno)
    -- on子句
    -- natural、using的缺点:都必须有同名列
    -- 连接查询要求两个表必须由关联(比如emp的deptno和dept的deptno),但是不要同名
    -- 如果有关联,但是不同名,该怎么解决?
    select empno,ename,d.deptno,d.dname -- 关联列必须使用前缀
    from emp e
    join dept d
    on(e.deptno = d.deptno) -- 此处e和d的deptno碰巧同名了
    -- 查询员工的编号、姓名、部门编号、部门的名称,要求薪水大于2000
    select empno,ename,d.deptno,d.dname
    from emp e
    join dept d
    on(e.deptno = d.deptno)
    where sal > 2000
    -- 小结:
    -- 实际开发中尽量使用on子句,不管是否有同名列,都可以使用;虽然稍显复杂,但是可读性高
    -- SQL99连接查询的优点:连接条件和筛选条件是分开的
    -- 连接条件:on(e.deptno = d.deptno) using(deptno) natural cross
    -- 筛选条件:where sal > 2000
    -- SQL92中,连接条件和筛选条件是没有分开的
    • 外连接查询
    -- SQL99外连接查询
    select * from dept
    select * from emp
    update emp set deptno = null where empno = 7788; -- 把scott员工设置成没有部门
    select *
    from emp e
    join dept d
    on(e.deptno = d.deptno) -- 返回13条记录,缺少了没有部门的员工scott,缺少了没有员工的部门40;只显示匹配的数据
    -- 左外连接
    select *
    from emp e
    left join dept d
    on(e.deptno = d.deptno)
    -- 右外连接
    select *
    from emp e
    right join dept d
    on(e.deptno = d.deptno)
    -- 全外连接
    select *
    from emp e
    full join dept d
    on(e.deptno = d.deptno) -- mysql中没有全外连接
    -- 曲线救国
    select *
    from emp e
    left join dept d
    on(e.deptno = d.deptno)
    union -- 使用union关键字可以曲线实现全外连接
    select *
    from emp e
    right join dept d
    on(e.deptno = d.deptno)
    • group by having练习
    -- 统计各部门的平均工资(只显示平均工资2000以上的)
    select deptno,avg(sal)
    from emp
    group by deptno
    having avg(sal) > 2000
    order by avg(sal)
    select avg(sal) from emp -- 这是所有部门的平均工资
    select deptno from emp
    select deptno,avg(sal) from emp -- 字段不能和分组函数共存,除非该字段是分组group by字段
    select deptno,avg(sal)
    from emp
    group by deptno
    select deptno,avg(sal)
    from emp
    -- where avg(sal) > 2000 -- where 子句不能使用多行函数(分组函数)
    group by deptno
    having avg(sal) >2000 -- 各个子句的书写是有顺序的
    order by avg(sal) desc
    -- 统计各个岗位的平均工资,除了manager
    select distinct job from emp
    select job,avg(sal)
    from emp
    group by job 
    having job != 'MANAGER'
    order by avg(sal)
    select job,avg(sal)
    from emp
    group by job 
    having job != 'MANAGER' && job != 'PRESIDENT'
    order by avg(sal)
    -- where 子句不能使用多行函数(分组函数)
    select job,avg(sal),count(1)
    from emp
    where count(1) > 3
    group by JOB
    -- 如果没有group by子句,select列表中不允许出现字段(单行函数)与多行函数混用的情况
    -- 出现在select列表中的字段,如果不是包含在多行函数中,那么该字段必须同时在group by子句中出现
    -- 不允许在where子句中使用多行函数
    -- 小结
    -- where子句和having子句的联系和区别
    -- 联系
    -- 都是筛选记录
    -- 区别
    -- ◆where是group by之前,having是group by之后
    -- ◆where中不能出现在多行函数,having中可以出现多行函数
    -- select语句总结
    -- ◆select语法格式
    -- ◆select column,group_function(column)
    -- ◆from table
    -- ◆[where condition]
    -- ◆[group by group_by_expression]
    -- ◆[having group_condition]
    -- ◆[order by column]
    -- ◆select语句执行顺序
    -- ◆from--->where--->group by--->select-having--->order by
    • group by having加强练习
    -- 列出工资最小值小于2000的职位
    select job,min(sal)
    from emp
    group by job 
    having min(sal) < 2000
    order by min(sal)
    -- 获取各个职位的最小工资
    select job,min(sal)
    from emp
    group by job
    having min(sal)
    order by min(sal) desc -- 按最小工资降序排列
    -- 获取各个职位的最小工资,筛选出小于2000的
    select job,min(sal)
    from emp
    group by job
    having min(sal) < 2000
    -- 列出平局工资大于1200元的部门和工作搭配组合
    select * from emp
    select * from dept
    select distinct deptno from emp 
    select distinct job from emp 
    select distinct job,deptno from emp
    select deptno,job,avg(sal),count(1)
    from emp 
    group by deptno,job
    having avg(sal) > 1200
    order by avg(sal) desc
    -- 统计人数小于4的部门的平均工资
    select deptno,avg(sal),count(1)
    from emp 
    group by deptno
    having count(1) < 4
    -- 统计各部门的最高工资,排除最高工资小于3000的部门
    select deptno,max(sal)
    from emp
    group by deptno
    having max(sal) >= 3000
    order by max(sal) 

    一休哥~~~

  • 相关阅读:
    2019长安大学ACM校赛网络同步赛 J Binary Number(组合数学+贪心)
    棋盘问题
    DP待整理
    Monkey and Banana(DP)
    Ignatius and the Princess IV
    【[kuangbin带你飞]专题十二 基础DP1】Max Sum Plus Plus(DP+滚动数组)
    第三届山东ACM Pick apples
    第三届山东省ACM The Best Seat in ACM Contest
    第三届山东ACM省赛 Pixel density
    第三届山东ACM省赛 n a^o7 !
  • 原文地址:https://www.cnblogs.com/sinoaccer/p/11938944.html
Copyright © 2011-2022 走看看