• 联表查询JoinON详解(自连接)


    链表查询

    JOIN

     

     

    例子:

    (1)创建school数据库

    1. CREATE DATABASE IF NOT EXISTS `school`;
    2. -- 创建一个school数据库
    3. USE `school`;-- 创建学生表
    4. DROP TABLE IF EXISTS `student`;
    5. CREATE TABLE `student`(
    6. `studentno` INT(4) NOT NULL COMMENT '学号',
    7. `loginpwd` VARCHAR(20) DEFAULT NULL,
    8. `studentname` VARCHAR(20) DEFAULT NULL COMMENT '学生姓名',
    9. `sex` TINYINT(1) DEFAULT NULL COMMENT '性别,0或1',
    10. `gradeid` INT(11) DEFAULT NULL COMMENT '年级编号',
    11. `phone` VARCHAR(50) NOT NULL COMMENT '联系电话,允许为空',
    12. `address` VARCHAR(255) NOT NULL COMMENT '地址,允许为空',
    13. `borndate` DATETIME DEFAULT NULL COMMENT '出生时间',
    14. `email` VARCHAR (50) NOT NULL COMMENT '邮箱账号允许为空',
    15. `identitycard` VARCHAR(18) DEFAULT NULL COMMENT '身份证号',
    16. PRIMARY KEY (`studentno`),
    17. UNIQUE KEY `identitycard`(`identitycard`),
    18. KEY `email` (`email`)
    19. )ENGINE=MYISAM DEFAULT CHARSET=utf8;
    20. -- 创建年级表
    21. DROP TABLE IF EXISTS `grade`;
    22. CREATE TABLE `grade`(
    23. `gradeid` INT(11) NOT NULL AUTO_INCREMENT COMMENT '年级编号',
    24. `gradename` VARCHAR(50) NOT NULL COMMENT '年级名称',
    25. PRIMARY KEY (`gradeid`)
    26. ) ENGINE=INNODB AUTO_INCREMENT = 6 DEFAULT CHARSET = utf8;
    27. -- 创建科目表
    28. DROP TABLE IF EXISTS `subject`;
    29. CREATE TABLE `subject`(
    30. `subjectno`INT(11) NOT NULL AUTO_INCREMENT COMMENT '课程编号',
    31. `subjectname` VARCHAR(50) DEFAULT NULL COMMENT '课程名称',
    32. `classhour` INT(4) DEFAULT NULL COMMENT '学时',
    33. `gradeid` INT(4) DEFAULT NULL COMMENT '年级编号',
    34. PRIMARY KEY (`subjectno`)
    35. )ENGINE = INNODB AUTO_INCREMENT = 19 DEFAULT CHARSET = utf8;
    36. -- 创建成绩表
    37. DROP TABLE IF EXISTS `result`;
    38. CREATE TABLE `result`(
    39. `studentno` INT(4) NOT NULL COMMENT '学号',
    40. `subjectno` INT(4) NOT NULL COMMENT '课程编号',
    41. `examdate` DATETIME NOT NULL COMMENT '考试日期',
    42. `studentresult` INT (4) NOT NULL COMMENT '考试成绩',
    43. KEY `subjectno` (`subjectno`)
    44. )ENGINE = INNODB DEFAULT CHARSET = utf8;

    输出结果:

    student

     

    result

     

    (2)查询参加了考试的同学(学号,姓名,科目编号,分数)

    1. -- ======= 联表查询 join ==============
    2. -- 查询参加了考试的同学(学号,姓名,科目编号,分数)
    3. SELECT * FROM student
    4. SELECT * FROM result

    思路:
    1、分析需求,分析查询的字段来自哪些表,(连接查询)
    2、确定使用哪种连接查询?--------------------------- 7种

    • 确定交叉点(这两个表中哪个数据是相同的)

    • 判断的条件:学生表中的 studentNo = 成绩表 studentNo

    • join(判断条件) on(连接的表) 连接查询

    •  where 等值查询

    • as是可以省略的,使用ON和where都是一样的

    INNER JOIN(内连接)

    1. -- INNER JOIN
    2. SELECT s.studentno,studentname,subjectno,studentresult
    3. FROM student AS s
    4. INNER JOIN result AS r
    5. WHERE s.studentno = r.studentno

    输出结果:

     

    RIGHT JOIN(右连接)

    1. -- RIGHT JOIN
    2. SELECT s.studentno,studentname,subjectno,studentresult
    3. FROM student AS s
    4. RIGHT JOIN result AS r
    5. ON s.studentno = r.studentno

    输出结果:

     

    left JOIN(左链接)

    1. -- left JOIN
    2. SELECT s.studentno,studentname,subjectno,studentresult
    3. FROM student AS s
    4. LEFT JOIN result AS r
    5. ON s.studentno = r.studentno

    输出结果:

     

    (3)查询缺考的同学

    1. -- 查询缺考的同学
    2. SELECT s.studentno,studentname,subjectno,studentresult
    3. FROM student AS s
    4. LEFT JOIN result AS r
    5. ON s.studentno = r.studentno
    6. WHERE studentresult IS NULL

    思考题(查询了参加考试的同学信息:学号,学生姓名,科目名,分数)

    1. 分析需求,分析查询的字段来自哪些表,student、result、subject(连接查询)
    2. 确定使用哪种连接查询? 7种
    3. 确定交叉点(这两个表中哪个数据是相同的)
    4. 判断的条件:学生表中的 studentNo = 成绩表 studentNo
    5. s.后面不能加`` 其他的都可以加``
    1. -- s.后面不能加`` 其他的都可以加``
    2. SELECT s.studentno,`studentname`,`subjectname`,`studentresult`
    3. FROM `student` AS s
    4. RIGHT JOIN `result` AS r
    5. ON r.studentno = s.studentno
    6. INNER JOIN `subject` AS sub
    7. ON r.subjectno = sub.subjectno

    输出结果:

    操作描述
    Inner join如果表中至少有一个匹配,就返回行
    left join会从左表中返回所有的值,即使右表中没有匹配
    right join会从右表中返回所有的值,即使左表中没有匹配

    总结:

    • 我要查询哪些数据 select....
    • 从那几个表中查 FROM (表 XXX) join (连接表) ON (交叉条件)
    • 假设存在一种多张表查询,慢慢来,先查询两张表然后再慢慢增加
    • FROM a left join b 这个就是把a表全部包括,再去找b中的东西,没有就是null(左连接)
    • FROM a right join b 这个就是把b表全部包括,再去找a中的东西,没有就是null(右连接)


    自连接及链表查询

    自连接

            自己的表和自己的表连接,核心:一张表拆为两张一样的表即可

    例子:

     

    父类 

            先看pid,去找相同的pid(pid = 1),然后去列出对应的categoryid

    categoryidcategoryName
    2信息安全
    3软件开发
    5美术设计

    子类     

    pidcategoryidcategoryName
    34数据库
    28办公信息
    36web开发
    57ps技术

    操作:查询父类对应的子类关系

            子类的pid去对应父类的categoryid

    父类子类
    软件开发数据库
    信息安全办公系统
    软件开发web开发
    美术设计ps技术

    1. -- ==================自连接=======
    2. CREATE TABLE `category`(
    3. `categoryid` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主题id',
    4. `pid` INT(10) NOT NULL COMMENT '父id',
    5. `categoryname` VARCHAR(50) NOT NULL COMMENT '主题名字',
    6. PRIMARY KEY (`categoryid`)
    7. )ENGINE=INNODB AUTO_INCREMENT=9 DEFAULT CHARSET = utf8;
    8. INSERT INTO `category` (`categoryid`, `pid`, `categoryname`)
    9. VALUES ('2','1','信息技术'),
    10. ('3','1','软件开发'),
    11. ('5','1','美术设计'),
    12. ('4','3','数据库'),
    13. ('8','2','办公信息'),
    14. ('6','3','web开发'),
    15. ('7','5','ps技术');
    16. -- 查询父子信息:把一张表看成为两个一摸一样的表
    17. SELECT a.`categoryname` AS '父栏目',b.`categoryname` AS '子栏目'
    18. FROM `category` AS a,`category` AS b
    19. WHERE a.`categoryid` = b.`pid`
    20. -- 查询学员所属的年级(学号,学生的姓名,年级名称)
    21. SELECT studentno,studentname,`gradename`
    22. FROM student AS s
    23. INNER JOIN `grade` AS g
    24. ON s.`gradeid` = g.`gradeid`
    25. -- 查询科目所属的年级(科目名称,年级名称)
    26. SELECT `subjectname`,`gradename`
    27. FROM `subject` AS sub
    28. INNER JOIN `grade` AS g
    29. ON sub.`gradeid` = g.`gradeid`
    30. -- 查询了参加 数据库结构-1 考试的同学信息:学号,学生姓名,科目名,分数
    31. SELECT s.`studentno`,`studentname`,`subjectname`,`studentresult`
    32. FROM `student` AS s
    33. INNER JOIN `result` AS r
    34. ON s.`studentno`=r.`studentno`
    35. INNER JOIN `subject` AS sub
    36. ON sub.`subjectno` = r.`subjectno`
    37. WHERE `subjectname` = '数据结构-1'

    SELECT语法

    1. SELECT [ALL | DISTINCT]
    2. {* | table.* | [table.field1[AS aliasl][, table.field2[AS alias2]][,.....]]}
    3. FROM table_name [AS table_alias]
    4. [LEFT | RIGHT | ineer JOIN table_name2] -- 联合查询
    5. [WHERE ....] -- 指定结果需满足的条件
    6. [GROUP by.....] -- 指定结果按照哪几个字段来分组
    7. [HAVING] -- 过滤分组的记录必须满足的次要条件
    8. [ORDER by.....] -- 指定查询记录按一次或多个条件排序
    9. [LIMIT {[OFFSET,]ROW_COUNT | row_countoffset OFFSET}]
    10. -- 指定查询的记录从哪条到哪条

    注意:

    1. [ ]括号代表可选的
    2. {}括号代表必选的

  • 相关阅读:
    iNFTnews | 从5G到6G:创新与颠覆的竞赛
    K8s cert-manager配置PKCS12的TLS
    JS进阶-闭包
    Latex数学符号查表
    Redis 的数据被删除,内存占用还这么大?
    Allegro铜皮动静态切换操作指导
    三、Thread 类和Runnable 接口详解
    Java区分子类方法中重名的三种变量
    django3.2.14之docker下主从分离【亲测可用】
    ubuntu 20.04 设置 authorized_keys 让 VS Code ssh 远程免密连接
  • 原文地址:https://blog.csdn.net/qq_46423017/article/details/126170452