MySQL多表查询机制

目录
  • 1.前言
  • 2.等值连接和非等值连接
    • 2.1等值连接
    • 2.2非等值连接
  • 3.自连接和非自连接
    • 3.1自连接
    • 3.2非自连接
  • 4.内连接和外连接
    • 4.1测试数据
    • 4.2左外连接
    • 4.3右外连接
    • 4.4全外连接
  • 附录:测试数据SQL脚本

1. 前言

在SQL开发当中,多表联查是绝对绕不开的一种技能。同样的查询结果不同的写法其运行效率也是千差万别。

在实际开发当中,我见过(好像还写过~)不少又长又臭的查询SQL,数据量一上来查个十几分钟那是家常便饭。

因此,深入理解SQL的多表查询机制,少写一些慢查询,应该可以少挨点骂。

2. 等值连接和非等值连接

2.1 等值连接

等值连接是在多表查询中最基础,也最简单的一种,其值为所有满足条件的笛卡尔积。

在from后面,哪个表写在前面结果中哪个表的值就先出现,

如下:

select *
from student,
     family
where student.family_id = family.id;

等值连接查询结果:

阿里在最新发布的Java开发手册中强制要求,只要涉及多个表,必须在列名前加表的别名(或表名)进行限定

2.2 非等值连接

非等值连接是通过a表中的值在b表中的某一个范围来进行的,能够很好的满足预设定好的分段统计需求。

非等值连接有两种写法,使用between...and...或大于号小于号

第一种写法:使用between...and...

select a.discipline_name, a.score, b.grade_tag
from achievement a,
     achievement_grade b
where a.score between b.lowest_score and b.highest_score;

第二种写法:使用>=<=

select a.discipline_name, a.score, b.grade_tag
from achievement a,
     achievement_grade b
where a.score >= b.lowest_score
  and a.score <= b.highest_score;

非等值连接查询结果:

3. 自连接和非自连接

3.1 自连接

自连接,顾名思义就是同一张表自己跟自己连接,为了区分需要给表取不同的别名。如一张成绩表,需要查询所有分数比“语文”高的数据:

分数表:

若不使用自连接,需要先通过查询语文的分数,然后再查询大于这个分数的数据。

具体可以按如下步骤进行查询:

-- 先查询语文的分数
select score from achievement where discipline_name = '语文';

-- 再查询分数比语文分数更高的数据
select * from achievement where score > 76;

而使用自连接,则可以在一条sq语句里完成查询:

select a.*
from achievement a,
     achievement b
where b.discipline_name = '语文'
  and a.score > b.score;

自连接查询结果:

3.2 非自连接

除自连接外,其他的都叫非自连接~~~

4. 内连接和外连接

内连接和外连接的区分本质上是另一种分类方法,如内连接就是等值连接。

  • 内连接:合并具有同一列的两个或两个以上的表的行, 结果集中不包含一个表与另一个表不匹配的行
  • 外连接:两个表在连接过程中除了返回满足连接条件的行以外还返回左(或右)表中不满足条件的

行 ,这种连接称为左(或右) 外连接。没有匹配的行时, 结果表中相应的列为空(NULL)。

  • 左外连接:连接条件中左边的表也称为主表 ,右边的表称为从表 。
  • 右外连接:连接条件中右边的表也称为主表 ,左边的表称为从表 。
  • 全外连接

4.1 测试数据

测试用学生表student和家庭表family数据如下:

学生表数据:

家庭表数据:

4.2 左外连接

-- 查出student中的所有数据,不满足的显示为null
-- 这里student在前面
select a.*
from student a
         left join family b on a.family_id = b.id

左外连接查询结果:

4.3 右外连接

-- 查出student中的所有数据,不满足的显示为null
-- 这里student在后面
select a.*
from family b
         right join student a on b.id = a.family_id;

右外连接查询结果:

4.4 全外连接

很遗憾,MySQL不支持全外连接。

附录:测试数据SQL脚本

-- auto-generated definition
create table student
(
    id           int auto_increment
        primary key,
    student_id   int                                null comment '学号',
    student_name varchar(40)                        null comment '姓名',
    family_id    int                                null comment '家庭ID',
    create_time  datetime default CURRENT_TIMESTAMP null comment '创建时间'
)
    comment '学生表';

create table family
(
    id             int auto_increment
        primary key,
    family_name    varchar(40)                        null comment '家庭名称',
    family_address varchar(40)                        null comment '家庭地址',
    create_time    datetime default CURRENT_TIMESTAMP null comment '创建时间'
)
    comment '家庭表';

create table achievement
(
    id              int auto_increment
        primary key,
    score           int         null comment '分数',
    discipline_name varchar(40) null comment '学科名称',
    student_id      int         null comment '学号'
)
    comment '成绩表';

create table achievement_grade
(
    id            int auto_increment
        primary key,
    grade_tag     varchar(10)                        null comment '档次',
    lowest_score  int                                null comment '最低分',
    highest_score int                                null comment '最高分',
    create_time   datetime default CURRENT_TIMESTAMP null comment '创建时间'
)
    comment '分数档次表';

INSERT INTO achievement_grade (id, grade_tag, lowest_score, highest_score, create_time) VALUES (1, '不及格', 0, 60, '2022-03-02 11:44:01');
INSERT INTO achievement_grade (id, grade_tag, lowest_score, highest_score, create_time) VALUES (2, '良好', 60, 80, '2022-03-02 11:44:01');
INSERT INTO achievement_grade (id, grade_tag, lowest_score, highest_score, create_time) VALUES (3, '优秀', 80, 100, '2022-03-02 11:44:01');

INSERT INTO student (id, student_id, student_name, family_id, create_time) VALUES (1, 1, '张三', 1, '2022-03-02 09:55:01');
INSERT INTO student (id, student_id, student_name, family_id, create_time) VALUES (2, 2, '李四', 2, '2022-03-02 09:55:01');
INSERT INTO student (id, student_id, student_name, family_id, create_time) VALUES (3, 3, '王五', 3, '2022-03-02 09:55:01');
INSERT INTO student (id, student_id, student_name, family_id, create_time) VALUES (4, 4, '高飞', null, '2022-03-02 19:45:14');

INSERT INTO family (id, family_name, family_address, create_time) VALUES (1, '张三家', '北京', '2022-03-02 09:54:13');
INSERT INTO family (id, family_name, family_address, create_time) VALUES (2, '李四家', '上海', '2022-03-02 09:54:13');
INSERT INTO family (id, family_name, family_address, create_time) VALUES (3, '王五家', '西伯利亚', '2022-03-02 09:54:13');

INSERT INTO achievement (id, score, discipline_name, student_id) VALUES (1, 76, '语文', 1);
INSERT INTO achievement (id, score, discipline_name, student_id) VALUES (2, 80, '数学', 1);
INSERT INTO achievement (id, score, discipline_name, student_id) VALUES (3, 65, '英语', 1);
INSERT INTO achievement (id, score, discipline_name, student_id) VALUES (4, 98, '地理', 1);
INSERT INTO achievement (id, score, discipline_name, student_id) VALUES (5, 77, '历史', 1);
INSERT INTO achievement (id, score, discipline_name, student_id) VALUES (6, 69, '生物', 1);

到此这篇关于MySQL多表查询机制的文章就介绍到这了,更多相关MySQL多表查询内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • MySQL多表连接查询详解

    目录 多表连接查询 内连接 左连接 右连接 子查询 总结 多表连接查询 表与表之间的连接分为内连接和外连接 内连接:仅选出两张表互相匹配的记录 外连接:既包括两张表匹配的记录,也包括不匹配的记录,同时外连接又分为左外连接(左连接)和右外连接(右连接) 内连接 首先准备两张表 学生student表 分数score表 内连接:在每个表中找出符合条件的共有记录 查询student表中的学生姓名和分数 第一种写法:只使用where select a.s_name, b.s_score from stud

  • MySql数据库单表查询与多表连接查询效率对比

    这段时间在做项目的过程中,遇到一个模块,数据之间的联系很复杂,在建表的时候就很纠结,到底该怎么去处理这些复杂的数据呢,是单表查询,然后在业务层去处理数据间的关系,还是直接通过多表连接查询来处理数据关系呢? 通过查阅资料和阅读博客,有以下两个回答: 一.<高性能mysql>中的回答 很多高性能的应用都会对关联查询进行分解.简单地,可以对每个表进行一次单表查询,然后将结果在应用程序中进行关联.例如,下面这个查询: select * from tag join tag_post on tag_pos

  • MySQL多表查询的案例详解

    多表查询 案列说明 笛卡尔积的理解 select id,department_name from employees,departments;#错的 select id,department_id,department_name from employees CROSS JOIN departments;#错的 每个员工和每个部门匹配了一遍(查出的条目数=id数*department数) 错误原因:缺少连接条件 笛卡尔积的解决 编写连接条件: 表1.列 = 表二.列(若多个表连接,至少要用n-1

  • MySql多表查询 事务及DCL

    目录 一.多表查询 1.查询语法 2. 准备sql 3. 笛卡尔积 4.多表查询的分类 4.1 内连接查询 4.2 外链接查询 4.3 子查询 4.4 子查询不同情况 5.多表查询练习 二.事务 1. 事务的基本介绍 2. 操作 2.MySQL数据库中事务默认自动提交 3. 事务的四大特征 一.多表查询 1.查询语法 select   列名列表  from   表名列表  where.... 2. 准备sql # 创建部门表 CREATE TABLE dept( id INT PRIMARY K

  • MySQL多表查询的具体实例

    一 使用SELECT子句进行多表查询 SELECT 字段名 FROM 表1,表2 - WHERE 表1.字段 = 表2.字段 AND 其它查询条件 SELECT a.id,a.name,a.address,a.date,b.math,b.english,b.chinese FROM tb_demo065_tel AS b,tb_demo065 AS a WHERE a.id=b.id 注:在上面的的代码中,以两张表的id字段信息相同作为条件建立两表关联,但在实际开发中不应该这样使用,最好用主外键

  • mysql多表查询的几种分类详细

    目录 分类1:等值连接vs非等值连接 1.等值连接 2.非等值连接 分类2:自连接vs非自连接 分类3:内连接vs外连接 总结: 多表查询分类 分类1:等值连接 vs 非等值连接 1. 等值连接 SELECT employees.employee_id, employees.last_name, employees.department_id, departments.department_id, departments.location_id FROM employees, departmen

  • MySQL多表查询机制

    目录 1.前言 2.等值连接和非等值连接 2.1等值连接 2.2非等值连接 3.自连接和非自连接 3.1自连接 3.2非自连接 4.内连接和外连接 4.1测试数据 4.2左外连接 4.3右外连接 4.4全外连接 附录:测试数据SQL脚本 1. 前言 在SQL开发当中,多表联查是绝对绕不开的一种技能.同样的查询结果不同的写法其运行效率也是千差万别. 在实际开发当中,我见过(好像还写过~)不少又长又臭的查询SQL,数据量一上来查个十几分钟那是家常便饭. 因此,深入理解SQL的多表查询机制,少写一些慢

  • 解析Mysql多表查询的实现

    查询是数据库的核心,下面就为您介绍Mysql多表查询时如何实现的,如果您在Mysql多表查询方面遇到过问题,不妨一看.Mysql多表查询: 复制代码 代码如下: CREATE TABLE IF NOT EXISTS contact( contact_id int(11) NOT NULL AUTO_INCREMENT, user_name varchar(255), nom varchar(255), prenom varchar(255), mail varchar(64), passcode

  • MySQL联表查询的简单示例

    MySql会用到联表查询,对于刚学习的新手来说,可能会理解起来有难度.下面这篇文章就来给大家详细介绍MySQL联表查询的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧 关系型数据库,免不了表之间存在各种引用与关联.这些关联是通过主键与外键搭配来形成的.所以,取数据时,很大情况下单张表无法满足需求,额外的数据则需要将其他表加入到查询中来,这便是 JOIN 关键字完成的操作. MySQL 中 JOIN, CROSS JOIN 和 INNER JOIN 三者语法功能上相同,可

  • MySQL单表查询常见操作实例总结

    本文实例总结了MySQL单表查询常见操作.分享给大家供大家参考,具体如下: 创建fruits表: CREATE TABLE fruits ( f_id char(10) NOT NULL, s_id INT NOT NULL, f_name char(255) NOT NULL, f_price decimal(8,2) NOT NULL, PRIMARY KEY(f_id) ) ; INSERT INTO fruits (f_id, s_id, f_name, f_price) VALUES(

  • MySQL多表查询实例详解【链接查询、子查询等】

    本文实例讲述了MySQL多表查询.分享给大家供大家参考,具体如下: 准备工作:准备两张表,部门表(department).员工表(employee) create table department( id int, name varchar(20) ); create table employee( id int primary key auto_increment, name varchar(20), sex enum('male','female') not null default 'ma

  • MySQL单表查询操作实例详解【语法、约束、分组、聚合、过滤、排序等】

    本文实例讲述了MySQL单表查询操作.分享给大家供大家参考,具体如下: 语法 一.单表查询的语法 SELECT 字段1,字段2... FROM 表名                   WHERE 条件                   GROUP BY field                   HAVING 筛选                   ORDER BY field                   LIMIT 限制条数 二.关键字的执行优先级(重点) 重点中的重点:关键

  • MySQL联表查询基本操作之left-join常见的坑

    概述 对于中小体量的项目而言,联表查询是再常见不过的操作了,尤其是在做报表的时候.然而校对数据的时候,您发现坑了吗?本篇文章就 mysql 常用联表查询复现常见的坑. 基础环境 建表语句 DROP TABLE IF EXISTS `role`; CREATE TABLE `role` ( `id` int(11) NOT NULL AUTO_INCREMENT, `role_name` VARCHAR(50) DEFAULT NULL COMMENT '角色名', PRIMARY KEY (`i

  • MySQL多表查询详解下

    好好吃饭,好好休息,听着很简单,实际落实缺失不那么容易. 继续回顾MySql的多表查询之1999语法 #二,SQL1999语法 语法: SELECT 查询列表 FROM 表1 别名 [连接类型] JOIN 表2 别名 ON 链接条件 [WHERE 筛选条件] [GROUP BY 分组] [HAVING 筛选条件] [ORDER BY 排序列表ASC|DESC] 分类(连接类型): 内连接(★): INNER 外联结 左外(★):LEFT [OUTER] 右外(★):RIGHT [OUTER] 全

  • MySQL多表查询详解上

    时光在不经意间,总是过得出奇的快.小暑已过,进入中暑,太阳更加热烈的绽放着ta的光芒,...在外面被太阳照顾的人们啊,你们都是勤劳与可爱的人啊.在房子里已各种姿势看我这篇这章的你,既然点了进来,那就由我继续带你回顾MySql的知识吧! 回顾练习资料girls库以及两张表的脚本: 链接: https://pan.baidu.com/s/1bgFrP7dBBwk3Ao755pU4Qg 提取码: ihg7 引题:笛卡尔现象,先来观看一下两张表. SELECT * FROM boys; SELECT *

  • MySQL单表查询实例详解

    1.准备数据 以下操作将在该表中进行 create table student ( id int unsigned primary key auto_increment, name char(12) not null, gender enum("male","famale") default "male", age tinyint unsigned not null, hoc_group char(12) not null, html tinyi

随机推荐