当前位置: 首页 > news >正文

SQL JOIN 全解析:用 `users` 与 `orders` 表彻底掌握内连接、左连接、右连接

SQL JOIN 全解析:用 usersorders 表彻底掌握内连接、左连接、右连接

在日常开发中,SQL 的连接(JOIN)语句是数据库查询的核心技能。尤其在多表联合查询时,不掌握好 INNER JOINLEFT JOINRIGHT JOIN,你就很容易写出“行数膨胀”、数据丢失、NULL 满天飞的奇怪结果。

本文将用两张简单的表 users(用户)和 orders(订单)作为例子,深入讲解三种常见的连接方式。


一、准备工作:建表与数据

我们先创建两张表并插入一些测试数据。

表结构:

-- 用户表:左表
CREATE TABLE users (id INT PRIMARY KEY,name VARCHAR(50)
);-- 订单表:右表
CREATE TABLE orders (id INT PRIMARY KEY,user_id INT,item VARCHAR(100),FOREIGN KEY (user_id) REFERENCES users(id)
);

示例数据:

-- 插入用户数据
INSERT INTO users (id, name) VALUES
(1, '孙悟空'),
(2, '苏有朋'),
(3, '李白'),
(4, '赵云'),
(5, '诸葛亮');-- 插入订单数据
INSERT INTO orders (id, user_id, item) VALUES
(101, 1, '金箍棒'),
(102, 2, '琵琶'),
(103, 1, '筋斗云'),
(104, 99, '无主之剑');  -- 注意:user_id=99 不存在于 users 中

二、INNER JOIN:内连接

SELECT a.id, a.name, b.item
FROM users a
INNER JOIN orders b ON a.id = b.user_id;

结果:

idnameitem
1孙悟空金箍棒
2苏有朋琵琶
1孙悟空筋斗云

特点:

  • 只保留能成功匹配的记录。
  • user_id=99 的订单匹配不到 → 被排除。
  • 李白赵云诸葛亮没下单 → 被排除。
  • 孙悟空有两个订单 → 出现两次。

总结一句话:

内连接 = 两边都有才要。


三、LEFT JOIN:左连接

SELECT a.id, a.name, b.item
FROM users a
LEFT JOIN orders b ON a.id = b.user_id;

结果:

idnameitem
1孙悟空金箍棒
1孙悟空筋斗云
2苏有朋琵琶
3李白NULL
4赵云NULL
5诸葛亮NULL

特点:

  • 保留所有左表(users)数据
  • 匹配不到的订单信息 → 填充为 NULL
  • user_id=99 的订单仍然被丢弃。

总结一句话:

左连接 = 左边全保,右边能连就连,不能连就补 NULL。


四、RIGHT JOIN:右连接

SELECT a.id, a.name, b.item
FROM users a
RIGHT JOIN orders b ON a.id = b.user_id;

结果:

idnameitem
1孙悟空金箍棒
1孙悟空筋斗云
2苏有朋琵琶
NULLNULL无主之剑

特点:

  • 保留所有右表(orders)数据
  • 匹配不到的用户信息 → 补 NULL
  • user_id=99 没用户匹配 → 仍然出现在结果中。

总结一句话:

右连接 = 右边全保,左边对不上就补 NULL。


五、膨胀现象:JOIN 会让行数增加吗?

是的!比如:

SELECT a.*, b.*
FROM users a
LEFT JOIN orders b ON a.id = b.user_id;

你可能以为每个用户只出现一行,结果 孙悟空 出现了两次。

原因:

  • JOIN 会对满足条件的所有组合都生成结果。
  • 孙悟空有两个订单 → 出现两行。
  • 赵云没下单 → 也会保留一行(item=NULL)。

小贴士:

连接时不是“找一个就停”,而是“所有匹配的都拿出来”。


六、常见场景推荐

场景推荐 JOIN
只看有订单的用户INNER JOIN
列出所有用户 + 他们的订单情况LEFT JOIN
列出所有订单 + 是否找到下单用户RIGHT JOIN
查出哪些用户没有下单LEFT JOIN + WHERE b.id IS NULL

示例:

SELECT a.id, a.name
FROM users a
LEFT JOIN orders b ON a.id = b.user_id
WHERE b.id IS NULL;

结语

  • JOIN 本质上是“表之间的行配对”,不只是挑字段而已。
  • 行数会膨胀,尤其是一对多、多对多连接时尤为明显。
  • 熟练掌握 JOIN,才能写出既高效又准确的 SQL 查询。

一图了解JOIN

在这里插入图片描述

参考链接

  • SQL Joins Visualizer
    一目了然地展示各种 JOIN 类型行为。

  • LeetCode SQL Tutorial(JOIN 练习)
    通过实战题目巩固 JOIN 和子查询等知识点。

  • W3Schools:SQL JOIN
    基础入门首选,配有图解和在线练习。

  • MySQL JOIN 语法官方文档
    官方介绍各种 JOIN 的语法规则和性能提示。

  • PostgreSQL JOIN Types
    PostgreSQL 对 JOIN 的详细描述,适用于所有标准 SQL 数据库。

  • Join Data In SQL

在这里插入图片描述

http://www.dtcms.com/a/292720.html

相关文章:

  • PostgreSQL大数据集查询优化
  • 蓝桥杯51单片机
  • 第十四届蓝桥杯青少Scratch国赛真题——太空大战
  • 解决 NCCL 多节点通信问题:从 nranks 1 到 busbw 116 MB/s
  • 02-netty基础-java四种IO模型
  • 二、计算机网络技术——第3章:数据链路层
  • Yocto meta-toradex-security layer 使用 TI AM62 安全启动功能
  • vscode,cursor,Trae终端不能使用cnpm、npm、pnpm命令解决方案
  • QT RCC 文件
  • Hadoop调度器深度解析:FairScheduler与CapacityScheduler的优化策略
  • PHP获取淘宝拍立淘(以图搜图)API接口操作详解
  • Ext4文件系统全景解析
  • 【n8n教程笔记——工作流Workflow】文本课程(第一阶段)——1、导航编辑器界面(Navigating the editor UI)介绍
  • DOM编程全解析:操作、事件与存储实战指南
  • Baumer工业相机堡盟工业相机如何通过YoloV8深度学习模型实现水下鱼类识别(C#代码,UI界面版)
  • 深入浅出Proxy与Reflect:从“黑中介“到“数据管家“的进阶之路
  • 【openssl生成自签证书】
  • Redis持久化-AOF
  • OpenCV 零基础到项目实战 | DAY 1:图像基础与核心操作
  • UE5 UI 安全区
  • 基于springboot的医院资源管理系统(源码+论文)
  • nodejs:告别全局安装,npx 命令详解及其与 npm 的区别
  • 网络安全渗透攻击案例实战:某公司内网为目标的渗透测试全过程
  • 如何永久删除安卓设备中的照片(已验证)
  • 2025 年非关系型数据库全面指南:类型、优势
  • 【Android】Popup menu:弹出式菜单
  • 小玩 Lifecycle
  • imx6ull-系统移植篇17——linux顶层 Makefile(上)
  • ZooKeeper学习专栏(五):Java客户端开发(原生API)详解
  • map和set的应用与模拟实现