天天看点

学习MySql第四天

复习

  1. where

    and or like < > <= >= != <> between and is not in

  2. like

    % 0个,一个,多个字符 _ 仅代替一个字符

  3. order by

    asc desc

  4. limit
    • limit num1,num2
    • num1---从第几条数据开始
    • num2---显示多少条数据
    • 一页显示8条,第三页 limit 16,8
  5. 常用函数
    • concat -日期函数
      • now()
      • curdate()
      • curtime
      • date()
      • time()
      • extract(from 时间)
        • %c
        • %m
        • %y
        • %Y
        • %d
        • %h
        • %H
        • %i
        • %s
    • strtodate
    • ifnull(参数1,参数2) comm null--->0
  6. 6.聚合函数
    • sum(列)
    • avg(列)
    • count() * 1 符合where 条件的有多少条目总数
    • max()
    • min()
  7. 7.练习

    18.案例:查询品牌是联想,且价格在40000以上的商品名称和价格

    select title,price 
    from t_item
    where title like '%联想%' and price >40000;
               
    19.案例:查询品牌是三木,或价格在50以下的商品名称和价格
    select title,price
    from t_item
    where title like '%三木%' or price <50;
               
    20.案例:查询品牌是三木、广博、齐心的商品名称和价格
    selectd title,price
    from t_item
    where title like '%三木%' or title like '%广博%' or title like '%齐心%';
               
    21.案例:查询品牌不是联想、戴尔的商品名称和价格
    select title,price
    from t_itme
    where title not like '%联想%' and title not like '%戴尔%';
               
    22.案例:查找品牌是联想且价格大于10000的电脑名称
    select title
    from t_item
    where title like '%联想%' and price >10000 and title like '%电脑%';
               
    23.案例:查询联想或戴尔的电脑名称列表
    select title
    from t_item
    where (title like '%联想%' or title like '%戴尔%') and title like '%电脑%';
               
    24.案例:查询联想、戴尔、三木的商品名称列表
    select *
    from t_item
    where title like '%联想%' or title like '%戴尔%' or title like '%三木%';
               
    25.案例:查询不是戴尔的电脑名称列表
    select title
    from t_item
    where title not like '%戴尔%' and title like '%电脑%';
               
    26.案例:查询所有是记事本的商品品牌、名称和价格
    select item_type,title,price
    from t_item
    where title like '%记事本%'
               
  8. distinct
    • 查询emp表中所有的职位(去重)

      select distinct job from emp;

    • 查询emp表中部门编号(去重)

      select distinct deptno from emp;

分组查询

- 查看每个部门的平均工资--错误演示

select avg(sal),deptno 
from emp
order by deptno;

select avg(sal),deptno 
from emp
group by deptno;

select mgr,count(*)
from emp
group by mgr;
           
  • 分组查询通常和聚合函数一起使用
  • 一般情况下,查询字段中出现聚合函数和普通列,一起查询的时候,那么分组的条件就是普通列
  • 当select子句中含有聚合函数时,凡是不在聚合函数中的其他单独字段,都必须出现在group by子句中.
  • group by子句要写在order by之前,where后
  • group by 可以根据多个字段分组
    • 查看同部门同职位的平均工资

      select deptno,job,avg(sal) from emp group by deptno,job;

      • 查询部门平均工资 select deptno avg(sal) from emp group by deptno;
      • 查询每个领导有多少个员工,显示领导id和员工数量
      select mgr,count(*) from emp group by mgr;

练习

1.案例:查询emp表中每个部门的编号,人数,工资总和,最后根据人数进行升序排列,如果人数一致,根据工资总和降序排列。

    select deptno,count(*),sum(sal)
    from emp
    group by deptno
    order by count(*),sum(sal) desc;


    2.案例:查询工资在1000~3000之间的员工信息,每个部门的编号,平均工资,最低工资,最高工资,根据平均工资进行升序排列。

    select deptno,avg(sal),min(sal),max(sal)
    from emp
    where sal>=1000 and sal<=3000
    group by deptno
    order by avg(sal);

    3.案例:查询含有上级领导的员工,每个职业的人数,工资的总和,平均工资,最低工资,最后根据人数进行降序排列,如果人数一致,根据平均工资进行升序排列

    select count(*),sum(sal),avg(sal),min(sal),job
    from emp
    where mgr is not null
    group by job
    order by count(*) desc,avg(sal);

    4.案例:查询工资在1000~3000之间每一个员工的编号,姓名,职位,工资

        select empno,ename,job,sal
        from emp
        where sal between 1000 and 3000;

    5.案例:查询emp表中奖金在500~2000之间所有员工的编号,姓名,工资以及奖金

        select empno,ename,sal,comm 
        from emp
        where comm between 500 and 2000;

    6.案例:查询员工的编号是7369,7521,XXXX

        select * from emp
        where empno in(7369,7521,XXXX);  

    7.案例:查询emp表中,职位是ANALYST,

        select * from emp
        where job='ANALYST'

    8.案例:查询emp表中职位不是ANALYST,

        select * from emp
        where job!='ANALYST'
           

练习

-- 查询出所有分类商品所对应的库存总量

    select category_id,sum(num)
    from t_item
    group by category_id;

-- 查询出所有分类商品所对应的平均单价

    select category_id,avg(price)
    from t_item
    group by category_id;

-- 1. 每个部门的人数

        select deptno,count(*)
        from emp
        group by deptno;

-- 2. 每个部门中,每个主管的手下人数

    select deptno,mgr,count(*)
    from emp
    group by deptno,mgr;

-- 3. 每种工作的平均工资

    select job,avg(sal)
    from emp
    group by job;

-- 提高题 4. 每年的入职人数

    select count(*),extract(year from hiredate) year
    from emp
    group by year;
           

有条件分组统计

HAVING 子句

错误演示

- 查询部门的平均工资,前提是该部门的平均工资高于2000

    select avg(sal),deptno
    from emp
    where avg(sal)>2000
    group by deptno;
           

正确效果

select avg(sal),deptno
    from emp
    group by deptno
    having avg(sal)>2000;
           
学习MySql第四天
  • group by 使用having过滤条件
  • 在sql语句中添加having子句的原因,是因为where关键字无法与聚合函数一起使用
  • where条件用于过滤行数,having条件用于过滤分组数量
  • 执行顺序,首先执行where,然后执行group by,根据一个或多个列进行分组,之后执行having.对分组以后的数据再次过滤.最后执行排序order by
    -- 查询所有分类商品所对应的库存总量中,高于1000的总量
    
        select sum(num),category_id
        from t_item
        group by category_id
        having sum(num)>1000;
    
    
    -- 查询所有分类商品所对应的平均单价中,低于100的均价
    
        select avg(price),category_id
        from t_item
        group by category_id
        having avg(price)<=100;
    
    -- 查询编号238和编号917分类商品的平均单价
    
        select avg(price),category_id
        from t_item
        group by category_id
        having category_id in (238,917);
    
        select avg(price),category_id
        from t_item
        where category_id in (238,917)
        group by category_id;
               
  • 总结,having子句经常跟聚合函数一起使用,如果没有使用到聚合函数,要注意是否可以写在where中,如果可以写在where,优先使用where过滤

课堂练习

1.案例:查询emp表中,每个部门的平均工资高于2000的部门的编号,部门的人数,平均工资,  最后根据平均工资进行升序排列。

    select deptno,count(*),avg(sal)
    from emp
    group by deptno
    having avg(sal)>2000
    order by avg(sal);

2.案例:查询emp表中名字中不是以'K'开头的信息,每个部门的最低工资高于1000的部门的编号,工资总和,平均工资以及最低工资,最后根据平均工资进行升序排列。

    select deptno,sum(sal),avg(sal),min(sal)
    from emp
    where ename not like 'K%'
    group by deptno
    having min(sal)>1000
    order by avg(sal) asc;

3.案例:查询emp表中部门编号是10,30号部门的员工,每个职业的最高工资低于5000的职业的名称,人数,平均工资,最高工资,最后根据人数进行升序排列,如果人数一致,根据最高工资进行降序排列。

    select job,count(*),avg(sal),max(sal)
    from emp
    where deptno in (10,30)
    group by job
    having max(sal)<=5000
    order by count(*),max(sal) desc;


4.案例:查询emp表中,每个部门的编号,人数,工资总和,最高工资以及最低工资,过滤掉最高工资是5000的部门,根据部门的人数进行升序排列,如果人数一致,则根据最高工资进行降序排列。

    select deptno,count(*),sum(sal),max(sal),min(sal)
    from emp
    group by deptno
    having max(sal)!=5000
    order by count(*),max(sal) desc;

5.案例:查询emp表中工资在1000~3000之间的员工信息,每个部门的编号,工资总和,平均工资,过滤掉平均工资低于2000的部门,按照平均工资进行升序排列
    select deptno,sum(sal),avg(sal)
    from emp
    where sal>=1000 and sal<=3000
    group by deptno
    having avg(sal)>=2000
    order by avg(sal);

6.案例:查询emp表中名字不是以‘S’开头,每个职位的名字,人数,工资总和,最高工资,过滤掉工资是3000的职位,根据人数进行升序排列,如果人数一致,根据工资总和进行降序排列。

    select job,count(*),sum(sal),max(sal)
    from emp
    where ename not like 'S%' and sal!=3000
    group by job
    order by count(*) ,sum(sal) desc;


7.案例:查询emp表的信息,每个职位的名称,人数,平均工资,最低工资,过滤掉平均工资是3000的职位信息,根据人数进行降序排列,如果人数一致,根据平均工资进行升序排列

    select job,count(*),avg(sal),min(sal)
    from emp
    group by job
    having avg(sal)!=3000
    order by count(*) desc,avg(sal);
           

子查询

MySQL子查询

  1. 子查询是指,在DML语句,嵌套了另外一个查询(DQL)语句
  2. 某些DDL也可以使用子查询
  3. 子查询语句,称为内部查询,而包含子查询的查询语句,称为外部查询
  4. 常用的子查询会出现两种
    • 外部查询的where子句使用子查询
    • 子查询在from后面,用子查询的结果集充当一张表
  5. 子查询可以在表达式的任何地方使用,但是必须在括号中关闭
  6. 子查询可以嵌套在另外一个子查询中
    1.案例:拿最低工资的员工信息
    
        select min(sal) from emp
    
        select * 
        from emp
        where sal=(select min(sal) from emp);
    
    2.案例:工资多于平均工资的员工信息
    
        select avg(sal) from emp;
    
        select *
        from emp
        where sal>(select avg(sal) from emp);
    
    3.案例:最后入职的员工信息
        select empno,ename,hiredate
        from emp
        where hiredate=(select max(hiredate) from emp);
    
    4.案例:查询出有商品的 分类信息
    
        select distinct category_id from t_item;
    
        select *
        from t_item_category
        where id in (select distinct category_id from t_item);
    
    5.案例:查询工资高于20号部门最高工资的员工的所有信息
    
        select max(sal)
        from emp
        where deptno=20;
    
        select *
        from emp
        where sal>(select max(sal)
                   from emp
                   where deptno=20);
    
    6.案例:查询emp表中姓名是‘KING’所属的部门的编号,名称
    
        select deptno 
        from emp
        where ename='KING';
    
        select deptno,dname 
        from dept
        where deptno=(select deptno 
                      from emp
                      where ename='KING');
    
    
    7.案例:查询部门名称是SALES的部门下所有员工的编号,姓名,职位,以及所属部门的编号
    
        select empno,ename,job,deptno
        from emp
        where deptno=(select deptno
                      from dept
                      where dname='SALES');
    
    8.案例:查询部门地址是DALLAS的部门下所有员工的所有信息(查询在DALLAS工作的所有员工信息)
    
        select *
        from emp
        where deptno=(select deptno 
                      from dept
                      where loc='DALLAS');
    
    9.案例:查询跟JONES同样工作的员工的所有信息(包含JONES)
    
        select *
        from emp
        where job=(select job from emp
                   where ename='JONES');
    
    不包含JONES
    
        select *
        from emp
        where job=(select job from emp
                   where ename='JONES') and ename <>'JONES';
               

关联查询数据

  • 从多张表中查询相应记录信息emp.deptno dept.deptno
  • 关联查询的重点在于这些表中记录的对应关系,这个关系也称为连接条件(关联条件)
  • 查看每个员工的名字以及所在部门的名字

    select e.ename,d.dname from emp e,dept d where e.deptno=d.deptno;

  • 如果不写关联关系

    select e.ename,d.dname from emp e,dept d;

笛卡尔积

  • 当多表关联时,如果没有写关联条件,返回的结果集是这几张表条目数的乘积,这个乘积就叫做笛卡尔积
  • 多数情况下,笛卡尔积是无意义的
  • 非常耗费资源,要尽量避免
    1.查看在new york工作的员工
    
        select e.ename,d.loc
        from emp e,dept d
        where e.deptno=d.deptno and d.loc='NEW YORK';
    
    2.查看工资高于3000的员工,名字,工资,部门名,所在地
    
    select e.ename,e.sal,d.dname,d.loc
    from emp e,dept d       
    where e.deptno=d.deptno and e.sal>3000;
               

等值连接/内连接

  • 语法
    select * from A,B where A.某字段=B.某字段;
    select * from A join B on A.某字段=B.某字段;
    完整版:
    select * from A [inner] join B on A.某字段=B.某字段;
    
    1.查看在new york工作的员工
    
        select e.ename,d.loc
        from emp e,dept d
        where e.deptno=d.deptno and d.loc='NEW YORK';
    
        select e.ename,d.loc
        from emp e join dept d
        on e.deptno=d.deptno
        where d.loc='NEW YORK';
    
    2.查看工资高于3000的员工,名字,工资,部门名,所在地
    
        select e.ename,e.sal,d.dname,d.loc
        from emp e join dept d
        on e.deptno=d.deptno
        where e.sal>3000;
               
  • 不满足连接条件的记录是不会在关联查询中被查询出来的
    select e.ename,e.sal,d.dname,d.loc,d.deptno
        from emp e join dept d
        on e.deptno=d.deptno;
               

左外连接

  • 以join左侧表作为基准表(驱动表--所有数据都会被显示出来,不管是否符合连接条件),那么当该表中某条记录不满足连接条件时,来自右表的字段全部为null
  • 语法 select * from A left join B on 连接条件;
    select e.ename,e.sal,d.dname,d.loc,d.deptno
    from dept d left join emp e
    on e.deptno=d.deptno;
               

右外连接

  • 以join右侧表作为基准表(驱动表--所有数据都会被显示出来,不管是否符合连接条件),那么当该表中某条记录不满足连接条件时,来自左表的字段全部为null
  • 语法 select * from A right join B on 连接条件;
    select e.ename,e.sal,d.dname,d.loc,d.deptno
    from emp e right join dept d
    on e.deptno=d.deptno;
               

关联查询数据案例

代码实践
-- 查询出所有可以匹配的商品分类及商品数据

    select *
    from t_item t1 join t_item_category t2
    on t1.category_id=t2.id;    

-- 查询出所有的分类,以及与之匹配的商品

    select *
    from t_item t1 right join t_item_category t2
    on t1.category_id=t2.id;



-- 查询出所有的商品,以及与之匹配的分类

    select *
    from t_item t1 left join t_item_category t2
    on t1.category_id=t2.id;
           

强化练习

练习

  1. 每个部门的人数,根据人数排序
  2. 每个部门中,每个主管的手下人数
  3. 每种工作的平均工资
  4. 每年的入职人数
  5. 少于等于3个人的部门
  6. 拿最低工资的员工信息
  7. 只有一个下属的主管信息
  8. 平均工资最高的部门编号
  9. 下属人数最多的人,查询其个人信息
  10. 拿最低工资的人的信息
  11. 最后入职的员工信息
  12. 工资多于平均工资的员工信息
  13. 查询员工信息,部门名称
  14. 员工信息,部门名称,所在城市
  15. DALLAS 市所有的员工信息
  16. 按城市分组,计算每个城市的员工数量
  17. 查询员工信息和他的主管姓名
  18. 员工信息,员工主管名字,部门名
  19. 员工信息,部门名,和部门经理
  20. 员工和他所在部门名
  21. 案例:查询emp表中所有员工的编号,姓名,职位,工资以及工资的等级,根据工资的等级进行升序排列
  22. 案例:查询emp表中所有员工的编号,姓名,职位,工资以及该员工上级领导的编号,姓名,职位,工资
  23. 案例:查询emp表中名字中没有字母'K'的所有员工的编号,姓名,职位以及所在部门的编号,名称,地址 select e.empno,e.ename,e.job,d.deptno,d.dname,d.loc from emp e left join dept d on e.deptno=d.deptno where e.ename not like '%K%';
  24. 案例:查询dept表中所有的部门的所有的信息,以及与之关联的emp表中员工的编号,姓名,职位,工资
  25. 案例:查询emp表中所有员工的编号,姓名,职位,工资以及工资的等级,该等级的最低工资,按照员工的编号进行升序排列。 select e.empno,e.ename,e.job,e.sal,s.grade,s.losal from emp e left join salgrade s on e.sal between s.losal and s.hisal order by e.empno;

继续阅读