zoukankan      html  css  js  c++  java
  • Day055--MySQL--外键的变种,表与表的关系,单表查询,多表查询, 内连接,左右连接,全外连接

    表和表的关系 ---- 外键的变种 *

    一对多或多对一
    
    多对多
    
    一对一
    

    参考 https://www.cnblogs.com/majj/p/9169416.html
    如何找出两张表之间的关系

    分析步骤:
    #1、先站在左表的角度去找
    是否左表的多条记录可以对应右表的一条记录,如果是,则证明左表的一个字段foreign key 右表一个字段(通常是id)
    
    #2、再站在右表的角度去找
    是否右表的多条记录可以对应左表的一条记录,如果是,则证明右表的一个字段foreign key 左表一个字段(通常是id)
    
    #3、总结:
    #多对一:
    如果只有步骤1成立,则是左表多对一右表
    如果只有步骤2成立,则是右表多对一左表
    
    #多对多
    如果步骤1和2同时成立,则证明这两张表时一个双向的多对一,即多对多,需要定义一个这两张表的关系表来专门存放二者的关系
    
    #一对一:
    如果1和2都不成立,而是左表的一条记录唯一对应右表的一条记录,反之亦然。这种情况很简单,就是在左表foreign key右表的基础上,将左表的外键字段设置成unique即可
    

    单表查询 ***

    一、单表查询的语法
       SELECT 字段1,字段2... FROM 表名
                      WHERE 条件
                      GROUP BY field
                      HAVING 筛选
                      ORDER BY field
                      LIMIT 限制条数
    二、关键字的执行优先级(重点)
    
    重点中的重点:关键字的执行优先级
    from 
    where  		筛选
    group by 	分组
    having   	筛选, 一定用聚合
    select  
    distinct 去重
    order by	排序
    limit  限制结果显示数量
    	
    
    1.找到表:from
    
    2.拿着where指定的约束条件,去文件/表中取出一条条记录
    
    3.将取出的一条条记录进行分组group by,如果没有group by,则整体作为一组
    
    4.将分组的结果进行having过滤
    
    5.执行select
    
    6.去重
    
    7.将结果按条件排序:order by
    
    8.限制结果的显示条数
    

    where

    where子句中可以使用
    1.比较运算符:>、<、>=、<=、<>、!=
    2.between 80 and 100 :值在80到100之间
    3.in(80,90,100)值是10或20或30
    4.like 'xiaomagepattern': pattern可以是%或者_。%小时任意多字符,_表示一个字符
    5.逻辑运算符:在多个条件直接可以使用逻辑运算符 and or not
    

    group by

    group by 是发生在where之后,where条件是可选的

    针对于相同字段进行归类

    select * from employee group by post;
    

    注意: 分组之后 ,只能获取分组的字段,如果想获取组内的信息要通过聚合函数进行计算

    聚合函数

    max() 最大值
    min() 最小值
    sum() 求和
    count() 求总个数
    avg() 求平均值
    

    虚拟表

    # 起别名
    select A.a from (select post,count(1) as a from employee group by post) as A;
    

    小练习

    1. 查询岗位名以及岗位包含的所有员工名字
      select post,group_concat(name) from employee group by post;
    2. 查询岗位名以及各岗位内包含的员工个数
    3. 查询公司内男员工和女员工的个数
    4. 查询岗位名以及各岗位的平均薪资
    5. 查询岗位名以及各岗位的最高薪资
    6. 查询岗位名以及各岗位的最低薪资
    7. 查询男员工与男员工的平均薪资,女员工与女员工的平均薪资

    having

    Mysql 5.7 整体作为一组 可以执行sql

    select * from employee having salary>1000000;
    

    Mysql 5.6 5.5

    mysql>  select * from employee having salary>1000000;
    ERROR 1463 (42000): Non-grouping field 'salary' is used in HAVING clause
    # 必须分组之后才能使用having
    

    各组内平均年龄大于25岁的人数,平均年龄

    select count(1),avg(age),post from employee group by post having avg(age) > 25;
    
    select post, count(1),group_concat(name) from (select name, age, post from employee where post in 
    (select post as age_a from employee group by post having avg(age) > 25) and age >25) as n_a_p group by post;
    

    分组和having练习

    1. 查询各岗位内包含的员工个数小于2的岗位名、岗位内包含员工名字、个数
    2. 查询各岗位平均薪资大于10000的岗位名、平均工资
    3. 查询各岗位平均薪资大于10000且小于20000的岗位名、平均工资
    
    select post,group_concat(name),count(1) from employee group by post having count(1) < 2;
    
    select post,avg(salary) from employee group by post having avg(salary) > 10000;
    
    
    select post,avg(salary)  from employee group by post having avg(salary) > 10000 and avg(salary) < 20000;
    

    order by

    #先根据年龄进行升序 再根据id进行降序
    select * from employee order by age asc, id desc;
    
    
    
    2. 查询各岗位平均薪资大于10000的岗位名、平均工资,结果按平均薪资降序排列
    
    select post,avg(salary) as a from employee group by post having avg(salary) > 10000 order by a desc;
    

    limit 限制

    # 分页 分页不是这么简单
    select * from employee limit 0,5;
    select * from employee limit 5,5;
    select * from employee limit 10,5;
    

    多表查询 **

    多表连接查询

    笛卡尔积
    
    	
    
    
    
    # 符合条件查询
    select  * from employee,department where employee.dep_id = department.id;
    

    内连接

    只获取匹配的数据

    select * from employee inner join department on employee.dep_id = department.id;
    

    左连接 或右连接

    只显示左表所有记录

    select * from employee left join department on employee.dep_id = department.id;
    

    全外连接

    select * from employee left join department on employee.dep_id = department.id
      union
    select * from employee right join department on employee.dep_id = department.id;
    
    select * from employee left join department on employee.dep_id = department.id
      union all
    select * from employee right join department on employee.dep_id = department.id;
    
    #注意 union与union all的区别:union会去掉相同的纪录
    

    练习题

    1.即找出年龄大于25岁的员工以及员工所在的部门
    
    select department.name, employee.name,employee.age from employee left join department on employee.dep_id = department.id where age >25;  # xiaomage部门null
    
    select department.name, employee.name,employee.age from employee inner join department on employee.dep_id = department.id where age >25;  # 不包含没有部门的人
    

    子查询

    #1:子查询是将一个查询语句嵌套在另一个查询语句中。
    #2:内层查询语句的查询结果,可以为外层查询语句提供查询条件。
    #3:子查询中可以包含:IN、NOT IN、ANY、ALL、EXISTS 和 NOT EXISTS等关键字
    #4:还可以包含比较运算符:= 、 !=、> 、<等
    

    小练习

    #查询平均年龄在25岁以上的部门名
    select * from department where id in (select dep_id from employee group by dep_id having avg(age) > 25);
    # 查看技术部员工姓名
    
    #查看不足1人的部门名
    
    
    # 查询大于部门内平均年龄的员工名、年龄
    select name,age from employee inner join (select dep_id,avg(age) as av from employee group by dep_id) as B on employee.dep_id = B.dep_id where age > av;
  • 相关阅读:
    PostgreSQL-14-异常值处理
    Python-5-字符串方法
    Python-6-字典-函数dict,字典的基本操作及将字符串设置功能用于字典
    STP-6-快速生成树协议-新端口角色,状态和类型以及新链路类型
    PostgreSQL-13-缺失值处理
    IP服务-6-SNMP
    IP服务-7-系统日志
    Python-4-设置字符串的格式字符串
    IP服务-5-网络时间协议
    Python -3-列表和元组
  • 原文地址:https://www.cnblogs.com/surasun/p/10009550.html
Copyright © 2011-2022 走看看