zoukankan      html  css  js  c++  java
  • 关系连接查询

     

    高级 关系 连接

     
    复制代码
    select distinct 列*
    from 表1 innser|left|right join 表2 on 表1与表2的关系
    where ...
    group by ... (5个聚合函数,avg,max,sum,min,count)
    having ...
    order by ... (排序desc|asc)
    limit start,count
    复制代码

    1.关系

    • 创建成绩表scores,结构如下
      • id
      • 学生
      • 科目
      • 成绩
    • 思考:学生列应该存什么信息呢?
    • 答:学生列的数据不是在这里新建的,而应该从学生表引用过来,关系也是一条数据;根据范式要求应该存储学生的编号,而不是学生的姓名等其它信息
    • 同理,科目表也是关系列,引用科目表中的数据

        

    2.外键约束

    • 思考:怎么保证关系列数据的有效性呢?任何整数都可以吗?
    • 答:必须是学生表中id列存在的数据,可以通过外键约束进行数据的有效性验证
    • 为stuid添加外键约束
    alter table scores add constraint stu_sco foreign key(stuid) references students(id);
    • 在创建表时可以直接创建约束
    复制代码
    create table scores(
    id int primary key auto_increment,
    stuid int,
    subid int,
    score decimal(5,2),
    foreign key(stuid) references students(id),
    foreign key(subid) references subjects(id)
    );
    复制代码
    复制代码
    mysql> create table scores(
        -> id int auto_increment primary key not null,
        -> score decimal(4,1),
        -> stuid int,
        -> subid int,
        -> foreign key(stuid) references students(id),
        -> foreign key(subid) references subjects(id));
    复制代码
    • 添加数据
    复制代码
    mysql> insert into scores values(0,100,1,1);
    Query OK, 1 row affected (0.01 sec)
    
    mysql> select * from scores;
    +----+-------+-------+-------+
    | id | score | stuid | subid |
    +----+-------+-------+-------+
    |  1 | 100.0 |     1 |     1 |
    +----+-------+-------+-------+
    复制代码
    mysql> insert into scores values(0,100,10,10);
    ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`py31`.`scores`, CONSTRAINT `scores_ibfk_2` FOREIGN KEY (`subid`) REFERENCES `subjects` (`id`))

    3.外键的级联操作()逻辑删除

    • 在删除students表的数据时,如果这个id值在scores中已经存在,则会抛异常
    • 推荐使用逻辑删除,还可以解决这个问题
    • 可以创建表时指定级联操作,也可以在创建表后再修改外键的级联操作

    级联操作的类型包括:

    • restrict(限制):默认值,抛异常
    • cascade(级联):如果主表的记录删掉,则从表中相关联的记录都将被删除
    • set null:将外键设置为空
    • no action:什么都不做
    alter table scores add constraint stu_sco foreign key(stuid) references students(id) on delete cascade;

    4.连接查询

    • 问:查询每个学生每个科目的分数
    • 分析:学生姓名来源于students表,科目名称来源于subjects,分数来源于scores表,怎么将3个表放到一起查询,并将结果显示在同一个结果集中呢?
    • 答:当查询结果来源于多张表时,需要使用连接查询
    • 关键:找到表间的关系,当前的关系是
      • students表的id---scores表的stuid
      • subjects表的id---scores表的subid
    • 则上面问题的答案是:
    select students.sname,subjects.stitle,scores.score
    from scores
    inner join students on scores.stuid=students.id
    inner join subjects on scores.subid=subjects.id;

      1)查询成绩

    复制代码
    mysql> select * from scores;
    +----+-------+-------+-------+
    | id | score | stuid | subid |
    +----+-------+-------+-------+
    |  1 | 100.0 |     1 |     1 |
    |  3 | 100.0 |     3 |     2 |
    |  4 | 100.0 |     4 |     5 |
    |  5 |  94.0 |     3 |     5 |
    |  6 |  94.0 |     7 |     5 |
    |  7 |  92.0 |     7 |     5 |
    |  8 |  92.0 |     8 |     5 |
    |  9 |  72.0 |     8 |     5 |
    +----+-------+-------+-------+
    复制代码

      2)连接查询

    复制代码
    学生表 - 班级表
    
    郭靖 python 100
    student.name  
    subjects.title
    scores.score
    
    select students.name,subjects.title,scores.score 
    from scores 
    inner join students on scores.stuid=students.id
    inner join subjects on scores.subid=subjects.id;
    复制代码
    复制代码
    +-----------+---------+-------+
    | name      | title   | score |
    +-----------+---------+-------+
    | 腾旭      | python  | 100.0 |
    | 网易      | linux   | 100.0 |
    | 小米      | mysqlDB | 100.0 |
    | 网易      | mysqlDB |  94.0 |
    | QQ        | mysqlDB |  94.0 |
    | QQ        | mysqlDB |  92.0 |
    | 腾讯云    | mysqlDB |  92.0 |
    | 腾讯云    | mysqlDB |  72.0 |
    +-----------+---------+-------+
    复制代码
    • 表A inner join 表B:表A与表B匹配的行会出现在结果中
    select *
    from students inner join scores 
    on students.id=scores.stuid
    • 表A left join 表B:表A与表B匹配的行会出现在结果中,外加表A中独有的数据,未对应的数据使用null填充
    select *
    from students left join scores 
    on students.id=scores.stuid
    复制代码
    mysql> mysql> select * from students left join scores  on students.id=scores.stuid;
    +----+-----------+--------+---------------------+----------+------+-------+-------+-------+
    | id | name      | gender | birthday            | isDelete | id   | score | stuid | subid |
    +----+-----------+--------+---------------------+----------+------+-------+-------+-------+
    |  1 | 腾旭      |       | 1999-09-09 00:00:00 |          |    1 | 100.0 |     1 |     1 |
    |  3 | 网易      |       | NULL                |          |    3 | 100.0 |     3 |     2 |
    |  4 | 小米      |       | NULL                |          |    4 | 100.0 |     4 |     5 |
    |  3 | 网易      |       | NULL                |          |    5 |  94.0 |     3 |     5 |
    |  7 | QQ        |       | NULL                |          |    6 |  94.0 |     7 |     5 |
    |  7 | QQ        |       | NULL                |          |    7 |  92.0 |     7 |     5 |
    |  8 | 腾讯云    |       | NULL                |          |    8 |  92.0 |     8 |     5 |
    |  8 | 腾讯云    |       | NULL                |          |    9 |  72.0 |     8 |     5 |
    |  2 | 腾旭      |       | 1990-02-02 00:00:00 |          | NULL |  NULL |  NULL |  NULL |
    |  6 | 酷狗      |        | 2017-02-13 00:00:00 |         | NULL |  NULL |  NULL |  NULL |
    |  9 | 华为      |       | NULL                |          | NULL |  NULL |  NULL |  NULL |
    | 10 | 京东      |       | NULL                |          | NULL |  NULL |  NULL |  NULL |
    | 11 | 微博      |       | NULL                |          | NULL |  NULL |  NULL |  NULL |
    | 12 | 微信      |       | NULL                |          | NULL |  NULL |  NULL |  NULL |
    +----+-----------+--------+---------------------+----------+------+-------+-------+-------+
    复制代码
    • 表A right join 表B:表A与表B匹配的行会出现在结果中,外加表B中独有的数据,未对应的数据使用null填充
    select *
    from  scores right join students
    on students.id=scores.stuid
    复制代码
    +------+-------+-------+-------+----+-----------+--------+---------------------+----------+
    | id   | score | stuid | subid | id | name      | gender | birthday            | isDelete |
    +------+-------+-------+-------+----+-----------+--------+---------------------+----------+
    |    1 | 100.0 |     1 |     1 |  1 | 腾旭      |       | 1999-09-09 00:00:00 |          |
    |    3 | 100.0 |     3 |     2 |  3 | 网易      |       | NULL                |          |
    |    4 | 100.0 |     4 |     5 |  4 | 小米      |       | NULL                |          |
    |    5 |  94.0 |     3 |     5 |  3 | 网易      |       | NULL                |          |
    |    6 |  94.0 |     7 |     5 |  7 | QQ        |       | NULL                |          |
    |    7 |  92.0 |     7 |     5 |  7 | QQ        |       | NULL                |          |
    |    8 |  92.0 |     8 |     5 |  8 | 腾讯云    |       | NULL                |          |
    |    9 |  72.0 |     8 |     5 |  8 | 腾讯云    |       | NULL                |          |
    | NULL |  NULL |  NULL |  NULL |  2 | 腾旭      |       | 1990-02-02 00:00:00 |          |
    | NULL |  NULL |  NULL |  NULL |  6 | 酷狗      |        | 2017-02-13 00:00:00 |         |
    | NULL |  NULL |  NULL |  NULL |  9 | 华为      |       | NULL                |          |
    | NULL |  NULL |  NULL |  NULL | 10 | 京东      |       | NULL                |          |
    | NULL |  NULL |  NULL |  NULL | 11 | 微博      |       | NULL                |          |
    | NULL |  NULL |  NULL |  NULL | 12 | 微信      |       | NULL                |          |
    +------+-------+-------+-------+----+-----------+--------+---------------------+----------+
    复制代码

    5.练习

    • 查询学生的姓名、平均分
    复制代码
    mysql> select stuid,avg(score) from scores group by stuid;
    +-------+------------+
    | stuid | avg(score) |
    +-------+------------+
    |     1 |  100.00000 |
    |     3 |   97.00000 |
    |     4 |  100.00000 |
    |     7 |   93.00000 |
    |     8 |   82.00000 |
    +-------+------------+
    复制代码
    复制代码
    mysql> select stuid,avg(score) from scores  inner join students on  scores.stuid=students.id group by stuid;
    +-------+------------+
    | stuid | avg(score) |
    +-------+------------+
    |     1 |  100.00000 |
    |     3 |   97.00000 |
    |     4 |  100.00000 |
    |     7 |   93.00000 |
    |     8 |   82.00000 |
    +-------+------------+
    复制代码
    复制代码
    mysql> select name,stuid,avg(score) from scores  inner join students on  scores.stuuid=students.id group by stuid;
    +-----------+-------+------------+
    | name      | stuid | avg(score) |
    +-----------+-------+------------+
    | 腾旭      |     1 |  100.00000 |
    | 网易      |     3 |   97.00000 |
    | 小米      |     4 |  100.00000 |
    | QQ        |     7 |   93.00000 |
    | 腾讯云    |     8 |   82.00000 |
    +-----------+-------+------------+
    5 rows in set (0.00 sec)
    复制代码
    复制代码
    mysql> select name,avg(score) from scores  inner join students on  scores.stuid=students.id group by stuid;
    +-----------+------------+
    | name      | avg(score) |
    +-----------+------------+
    | 腾旭      |  100.00000 |
    | 网易      |   97.00000 |
    | 小米      |  100.00000 |
    | QQ        |   93.00000 |
    | 腾讯云    |   82.00000 |
    +-----------+------------+
    复制代码
    复制代码
    mysql> select name,avg(score) from scores  inner join students on  scores.stuid=students.id group by stuid order by avg(score) desc;
    +-----------+------------+
    | name      | avg(score) |
    +-----------+------------+
    | 小米      |  100.00000 |
    | 腾旭      |  100.00000 |
    | 网易      |   97.00000 |
    | QQ        |   93.00000 |
    | 腾讯云    |   82.00000 |
    +-----------+------------+
    复制代码
    • 查询男生的姓名、总分
    select students.sname,avg(scores.score)
    from scores
    inner join students on scores.stuid=students.id
    where students.gender=1
    group by students.sname;

         

    查询男生的姓名、总分
    students.gender=1
    students.name 
    sum(scores.score)
    建立连接:students.id=scores.stuid 
    使用sum 聚合 --》 分组 group by 姓名:每个人的总分
    select name,sum(score) 
    from students
    inner join scores on students.id=scores.stuid
    where gender=1 
    group by name   
    group by students.id  (如果同名)
    • 查询科目的名称、平均分
    select subjects.stitle,avg(scores.score)
    from scores
    inner join subjects on scores.subid=subjects.id
    group by subjects.stitle;
    复制代码
    查询科目的名称、平均分
    subjects.tilte
    avg(scores.score)
    
    建立连接:subjects.id=scores.subid
    使用avg ---》 group by subjects.title 
    
    select subjects.title,avg(scores.score)
    from scores
    inner join subjects on subjects.id=scores.subid
    group by subjects.title
    复制代码
    • 查询未删除科目的名称、最高分、平均分
    select subjects.stitle,avg(scores.score),max(scores.score)
    from scores
    inner join subjects on scores.subid=subjects.id
    where subjects.isdelete=0
    group by subjects.stitle;
    复制代码
    查询未删除科目的名称、最高分、平均分
    where subjects.isDelete=0
    subjects.tilte
    max(scores.score)
    avg(scores.score)
    
    建立连接subjects.id=scores.subid
    max avg --> group by subjects.tilte
    
    select subjects.title,max(scores.score),avg(scores.score)
    from subjects
    inner join scores on  subjects.id=scores.subid
    where subjects.isDelete=0
    group by subjects.title
    复制代码
     
     
     
     
     
     
  • 相关阅读:
    如何查看 SQL Server 执行的历史 SQL 语句记录?
    C# 父子窗体 传值
    java使用HttpURLConnection和HttpClient分别模拟get和post请求以及操作cookies
    selenium使用等待的几种方式
    初识selenium-grid
    selenium如何分别启动IE、firefox、chrome浏览器
    java在url传输前更改字符编码
    java获取Json和http状态码
    testng环境设置
    使用reportNG替换testNG的默认报告
  • 原文地址:https://www.cnblogs.com/Bighua123/p/8108212.html
Copyright © 2011-2022 走看看