MySQL -- 连接查询

MySQL使用连接查询(JOIN)是为了从多个相关表中获取数据。连接查询是一种强大且常用的操作,可以根据某些条件将两张或多张表中的数据组合在一起,返回一个联合结果集。

1.为什么使用连接查询

  1. 数据规范化

    • 数据库设计时通常会将数据拆分到不同的表中,以减少数据冗余和提高数据一致性。这种方法称为规范化。
    • 例如,将用户信息存储在一个表中,将订单信息存储在另一个表中。这时,如果你需要获取某用户的订单信息,就需要使用连接查询将这两个表的数据组合在一起。
  2. 提高查询效率

    • 通过使用连接查询,可以减少重复的数据存储,优化数据的管理和查询效率。
    • 比如,一个表中存储用户ID,另一个表中存储用户详细信息,查询时只需要连接用户ID和详细信息表即可获取完整信息,而不需要在单个表中存储冗余数据。
  3. 复杂查询需求

    • 在实际应用中,很多查询需求都涉及多个表的数据。例如,报表生成、数据分析、统计等都需要从多个表中提取相关数据。
    • 连接查询可以实现这些复杂的查询需求,通过合并相关表的数据来满足业务逻辑。

2.主要类型的连接查询

INNER JOIN

  • 仅返回两个表中满足连接条件的记录。
SELECT users.username, orders.order_id
FROM users
INNER JOIN orders ON users.user_id = orders.user_id;
  • 说明:这将返回所有用户和他们的订单,前提是用户和订单在两个表中都有匹配。

LEFT JOIN (或 LEFT OUTER JOIN)

  • 返回左表中的所有记录,即使右表中没有匹配的记录。如果右表没有匹配,则结果为NULL。
SELECT users.username, orders.order_id
FROM users
LEFT JOIN orders ON users.user_id = orders.user_id;
  • 说明:这将返回所有用户以及他们的订单。如果某个用户没有订单,则相应的订单ID将为NULL。

RIGHT JOIN (或 RIGHT OUTER JOIN)

  • 返回右表中的所有记录,即使左表中没有匹配的记录。如果左表没有匹配,则结果为NULL。
SELECT users.username, orders.order_id
FROM users
RIGHT JOIN orders ON users.user_id = orders.user_id;
users. Username
  • 说明:这将返回所有订单以及对应的用户。如果某个订单没有匹配的用户,则相应的用户名将为NULL。

FULL JOIN (或 FULL OUTER JOIN)

  • 返回左表和右表中的所有记录,如果没有匹配则返回NULL。MySQL不直接支持FULL JOIN,可以通过UNION实现。
SELECT users.username, orders.order_id
FROM users
LEFT JOIN orders ON users.user_id = orders.user_id
UNION
SELECT users.username, orders.order_id
FROM users
RIGHT JOIN orders ON users.user_id = orders.user_id;
users. Username

3.测试连接查询

  1. student 表

  • 存储学生的基本信息。
  • uid:学生的唯一标识(主键),自动递增。
  • name:学生姓名。
  • age:学生年龄。
  • sex:学生性别,使用枚举类型,值可以是'M'或'W'。
  1. course 表

  • 存储课程的基本信息。
  • cid:课程的唯一标识(主键),自动递增。
  • cname:课程名称。
  • credit:课程学分。
  1. exame 表

  • 存储考试信息,包括学生、课程和考试成绩。
  • uid:学生ID,对应student表中的uid
  • cid:课程ID,对应course表中的cid
  • time:考试时间。
  • score:考试成绩。
  • PRIMARY KEY(uid,cid):联合主键,确保每个学生在每门课程中只有一个成绩记录。
CREATE TABLE student(
uid INT UNSIGNED PRIMARY KEY NOT NULL AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
age TINYINT UNSIGNED NOT NULL,
sex ENUM('M','W') NOT NULL);

CREATE TABLE course(
cid INT UNSIGNED PRIMARY KEY NOT NULL AUTO_INCREMENT,
cname VARCHAR(50) NOT NULL,
credit TINYINT UNSIGNED NOT NULL);

CREATE TABLE exame(
uid INT UNSIGNED NOT NULL,
cid INT UNSIGNED NOT NULL,
time DATE NOT NULL,
score FLOAT NOT NULL,
PRIMARY KEY(uid,cid));

插入一些数据

-- 插入数据到 student 表
INSERT INTO student (name, age, sex) VALUES 
('Alice', 20, 'W'),
('Bob', 21, 'M'),
('Charlie', 22, 'M'),
('David', 20, 'M'),
('Eve', 21, 'W');

-- 插入数据到 course 表
INSERT INTO course (cname, credit) VALUES 
('Mathematics', 3),
('Physics', 4),
('Chemistry', 3),
('Biology', 2),
('Computer Science', 3);

-- 插入数据到 exame 表
INSERT INTO exame (uid, cid, time, score) VALUES 
(1, 1, '2024-01-10', 85.5),
(1, 2, '2024-01-11', 90.0),
(2, 1, '2024-01-9', 88.0),
(2, 3, '2024-01-10', 92.5),
(3, 4, '2024-01-12', 75.0),
(3, 5, '2024-01-9', 80.0),
(4, 2, '2024-01-12', 85.0),
(4, 3, '2024-01-12', 87.5),
(5, 1, '2024-01-11', 89.0),
(5, 5, '2024-01-11', 95.0);

 

 

 

 内连接

SELECT a.属性名1,a.属性名2,...,b,属性名1,b.属性名2... FROM table_name1 a inner join table_name2 b on a.id = b.id where a.属性名 满足某些条件;

预置条件:uid:1 cid:2
select score from exame where uid=1 and cid=2;
select a.uid,a.name,a.age,a.sex from student a where a.uid=1;
select c.score from exame c where c.uid=1 and c.cid=2;

连接两张表查询

// on a.uid=c.uid 区分大表 和 小表,按照数据量来区分,小表永远是整表扫描,然后去大表搜索 // 从student小表中取出所有的a.uid,然后拿着这些uid去exame大表中搜索 // 对于inner join内连接,过滤条件写在where的后面和on连接条件里面,效果是一样的

select a.uid,a.name,a.age,a.sex,c.score from student a
inner join exame c on a.uid=c.uid where c.uid=1 and c.cid=2;

select b.cid,b.cname,b.credit from course b where b.cid=2;

 

select a.uid,a.name,a.age,a.sex,b.cid,b.cname,b.credit,c.score
from exame c
inner join student a on c.uid=a.uid
inner join course b on c.cid=b.cid
where c.uid=1 and c.cid=2;

select a.uid,a.name,a.age,a.sex,b.cid,b.cname,b.credit,c.score
from exame c
inner join student a on c.uid=a.uid
inner join course b on c.cid=b.cid
where c.cid=2 and c.score>=90.0;

select b.cid,b.cname,b.credit,count(*)
from exame c
inner join course b on c.cid=b.cid
where c.score>=90.0
group by c.cid
having c.cid=2;//分组以后的过滤

select b.cid,b.cname,b.credit,count(*) cnt
from exame c
inner join course b on c.cid=b.cid
where c.score>=90.0
group by c.cid
order by cnt;

外连接查询

左连接查询

SELECT a.属性名列表, b.属性名列表 FROM table_name1 a LEFT [OUTER] JOIN table_name2 b on a.id = b.id;

// 把left这边的表所有的数据显示出来,在右表中不存在相应数据,则显示NULL
select a.* from User a left outer join Orderlist b on a.uid=b.uid where
a.orderid is null;

 例子:

 

select a.*,b.* from student a left join exame b on a.uid=b.uid;

找出没有考过试的

select a.*,b.* from student a left join exame b on a.uid=b.uid where b.cid is null;

内连接结果如下

左连接结果如下

 问题,为啥左连接没有把左表全部信息显示,左连接和内连接结果一样

若把where条件放到连接条件on后面

原因分析:

先用b.cid把b表过滤下

 这个内连接和外连接毫无区别,是一样的。所以外连接要把过滤条件写到on中

外连接查不存在的场景,还带有一定的限制条件,限制条件加到on的连接条件后面,where的过滤条件后面写null判空。

右连接查询

SELECT a.属性名列表, b.属性名列表 FROM table_name1 a LEFT [OUTER] JOIN table_name2 b on a.id = b.id;

// 把right这边的表所有的数据显示出来,在左表中不存在相应数据,则显示NULL
select a.* from User a right outer join Orderlist b on a.uid=b.uid where
b.orderid is null;
select * from student where uid not in (select distinct uid from exame);

 select distinct uid from exame-》会产生一张中间表存储结果供外面的sql来查询

not in 对于索引的命中并不高

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/676627.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

结账和反结账

结账与反结账功能在财务软件和会计系统中扮演着重要的角色,以下是关于这两个功能的详细解释: 一、结账功能 结账功能是计算和结转各个会计科目本期发生额和期末余额的过程,同时标志着一定时期内财务活动的结束和财务数据的固化。结账功能的…

Elo7下单购物教程:如何利用自养号测评提升产品曝光度?

Elo7 是巴西的一个独特电商平台,专注于手工艺品和定制商品。它被誉为“巴西的 Etsy”,为当地和国际手工艺者提供了一个销售其独特创作的市场。Elo7 成立于 2008 年,其主要目标是支持小型创业者和手工艺人,让他们能够将自己的作品推…

Hbase实战处理(一)关于hbase的表设计和集成

一、Hbase的原理讲解 1、hbase介绍 2、hbase集群架构(具体配置见其他文章) hbase集群的HA配置 (假如有3台机器(同时是regionserver角色),master、slaver1、slaver2) stop-hbase.sh cd /home/…

javascript导入excel文件

导入文件用到一个 xlsx.core.js 的包。 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><script type"tex…

vfrom二开给左边添加字段或者容器

例如&#xff0c;我在左侧加入一个 我的公司 字段 修改三个文件&#xff0c;这是文件目录 这个文件是当界面选择 简体中文 的时候&#xff0c;显示的 字段组件 或者 容器组件的中文名 这个文件是当界面选择 English 的时候&#xff0c;显示的 字段组件 或者 容器组件的英文名 把…

Java集合基础知识点系统性总结篇

目录 集合一、图解集合的继承体系&#xff1f;&#xff08;[图片来源](https://www.cnblogs.com/mrhgw/p/9728065.html)&#xff09;点击查看大图二、List,Set,Map三者的区别&#xff1f;三、List接口的实现3.1、Arraylist 、 LinkedList、Vector3.2、Arraylist 、 LinkedList、…

Java如何实现pdf转base64以及怎么反转?

问题需求 今天在做发送邮件功能的时候&#xff0c;发现邮件的附件部分&#xff0c;比如pdf文档&#xff0c;要求先把pdf转为base64&#xff0c;邮件才会发送。那接下来就先看看Java 如何把 pdf文档转为base64。 两种方式&#xff0c;一种是通过插件 jar 包的方式引入&#xf…

pyside6安装

目录 1. 安装2. 配置PyCharm环境3. 测试 1. 安装 打开Anaconda Prompt&#xff0c;执行以下命令创建虚拟环境并激活 # 创建名为 myEnv, python版本为3.9 的虚拟环境 conda create -n myEnv python3.9 # 激活创建的虚拟环境 conda avtivate myEnv使用pip安装Pyside6&#xff0…

git拉去代码报错“Failed to connect to 127.0.0.1 port 31181: Connection refused“

最近参与了一个新项目&#xff0c;在使用git clone 克隆代码时遇到了一个报错"fatal: unable to access ‘https://example.git/’: Failed to connect to 127.0.0.1 port 31181: Connection refused",今天就和大家分享下解决过程。 报错详情 在使用git clone 克隆…

回溯算法题模板与实战详解

文章目录 回溯算法模板实战详解全排列问题N皇后问题 组合总和问题子集问题括号生成问题单词搜索问题 回溯算法是一种通过试错的方式来寻找问题解决方案的算法&#xff0c;常用于解决约束满足问题、组合优化问题和排列组合问题。其核心思想是深度优先搜索(DFS)与剪枝策略的结合&…

Apipost IDEA 插件使用说明

Apipost Helper作为IDEA插件&#xff0c;可以快速生成和查询API文档&#xff0c;直观友好地在IDE中调试接口。它简化了开发流程并提升效率&#xff0c;即使新手也能够迅速掌握。Apipost Helper提供了诸多便捷功能&#xff0c;如通过代码查找接口或者通过接口查找代码等&#xf…

第十五届蓝桥杯物联网试题(国赛)

好&#xff0c;很好&#xff0c;国赛直接来个阅读理解&#xff0c;我猛做4个小时40分钟&#xff0c;cpu都干冒烟了&#xff0c;也算是勉强做完吧&#xff0c;做的很仓促&#xff0c;没多检查就交了&#xff0c;方波不会&#xff0c;A板有个指示灯没做&#xff0c;其他应该都还凑…

师彼长技以助己(3)逻辑思维

师彼长技以助己&#xff08;3&#xff09;逻辑思维 前言 上一篇文章进行了工程思维和产品思维的测试&#xff0c;并介绍了几个比较重要的产品思维模型。接下来本篇介绍工程思维。&#xff08;注意产品思维并不代表产品经理思维&#xff0c;工程思维也并不代表工程师思维&…

学习小心意——python的构造方法和析构方法

构造方法和析构方法分别用于初始化对象的属性和释放类占有的资源 构造方法_init_() 语法格式如下&#xff1a; class 类名:def __init__(self, 参数1, 参数2, ...):# 初始化代码self.属性1 参数1self.属性2 参数2# ... 示例代码如下 class Student:def __init__(self):s…

期权的权利金怎么算的

期权权利金的计算涉及多个因素&#xff0c;包括敲定价格、到期时间以及整个期权合约的具体情况。期权的权利金具体的计算公式和因素可能因不同的期权合约和市场条件而有所不同&#xff0c;下文为大家介绍期权的权利金怎么算的 &#xff1f;本文来自&#xff1a;期权酱 一、期权…

实战:Zig 编写高性能 Web 服务(1)

1.1 认识 std.http std.http 是 Zig 标准库中用于处理 HTTP 相关操作的类库。以我学习新的编程语言的经历来看&#xff0c;编写web程序是最常见的技术场景&#xff0c;所以熟练掌握 HTTP server/client 服务相关的编程知识是比较重要的。 std.http 主要包含以下API: Client…

19、matlab信号预处理中的中值滤波(medfilt1()函数)和萨维茨基-戈雷滤波滤(sgolayfilt()函数)

1、中值滤波&#xff1a;medfilt1()函数 说明&#xff1a;一维中值滤波 1&#xff09;语法 语法1&#xff1a;y medfilt1(x) 将输入向量x应用3阶一维中值滤波器。 语法2&#xff1a;y medfilt1(x,n) 将一个n阶一维中值滤波器应用于x。 语法3&#xff1a;y medfilt1(x,n…

Django中使用ModelForm保存数据

相对来说&#xff0c;使用ModelForm保存数据在Django中算是比较简单的。主要原因是ModelForm是建立在Django的模型&#xff08;Model&#xff09;之上的&#xff0c;它可以自动根据模型的定义生成表单&#xff0c;包括字段和验证规则。这样可以大大简化开发人员处理表单数据的工…

低空经济发展报告

低空经济是指利用低空空间进行商业开发和经济活动的概念。随着航空技术的发展和无人机的普及&#xff0c;低空经济逐渐成为一个新兴的经济领域。 低空经济可以涵盖的领域非常广泛&#xff0c;包括但不限于物流配送、农业植保、城市交通、旅游观光等。利用无人机等飞行器进行物…