SQL中on和where的区别

SQL中on和where的区别
  前言,在工作写SQL使用中,在涉及到多个表的关联时,既可以通过on进行数据过滤,又可以使用where进行数据过滤,

确实有点不太了解这两个关键字在left join后的区别,所以就去查了些资料,方便以后回顾。

数据库在通过连接两张或多张表来返回记录时,都会生成一张中间的临时表,然后再将这张临时表返回给用户。

在使用 left join 时,on 和 where 条件的区别如下:

1、on 条件是在生成临时表时使用的条件,它不管 on 中的条件是否为真,都会返回左边表中的记录。
2、where 条件是在临时表生成好后,再对临时表进行过滤的条件。这时已经没有 left join 的含义(必须返回左边表的记录)了,条件不为真的就全部过滤掉。
下面有两个表,用户表和用户地址表:表示用户和地址是1对多的关系

CREATE TABLE `t_user` (
  `id` int NOT NULL AUTO_INCREMENT,
  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '姓名',
  `age` int DEFAULT NULL COMMENT '年龄',
  `is_delete` int DEFAULT '0' COMMENT '0表示未删除,1表示已删除',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='用户表';
 
INSERT INTO `demo`.`t_user` (`id`, `name`, `age`, `is_delete`) VALUES (1, '张三', 23, 0);
INSERT INTO `demo`.`t_user` (`id`, `name`, `age`, `is_delete`) VALUES (2, '李四', 24, 1);
INSERT INTO `demo`.`t_user` (`id`, `name`, `age`, `is_delete`) VALUES (3, '王五', 25, 0);
 
 
CREATE TABLE `t_address` (
  `id` int NOT NULL AUTO_INCREMENT,
  `user_id` int DEFAULT NULL COMMENT '用户id',
  `address` varchar(255) DEFAULT NULL COMMENT '地址',
  `is_delete` int DEFAULT NULL COMMENT '0表示未删除,1表示已删除',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='用户地址表';
 
INSERT INTO `demo`.`t_address` (`id`, `user_id`, `address`, `is_delete`) VALUES (1, 1, '北京朝阳', 0);
INSERT INTO `demo`.`t_address` (`id`, `user_id`, `address`, `is_delete`) VALUES (2, 1, '北京丰台', 0);
INSERT INTO `demo`.`t_address` (`id`, `user_id`, `address`, `is_delete`) VALUES (3, 2, '北京西城', 1);
INSERT INTO `demo`.`t_address` (`id`, `user_id`, `address`, `is_delete`) VALUES (4, 5, '北京海淀', 1);

在这里插入图片描述
如果要查询已存在用户的地址信息,应该写在on后面还是where条件后面呢?请看下面示例:

条件都写在on后面(×)

如果将条件都写在on 后面,会发现用户表中is_delete为1的数据并没有被过滤(即使在on后面写了过滤条件‘u.is_delete = 0’)

SELECT
    u.`name`,
    u.age,
    u.is_delete,
    a.address
FROM
    t_user u
    LEFT JOIN t_address a ON u.id = a.user_id and u.is_delete = 0
    AND a.is_delete = 0;

在这里插入图片描述
条件都写在where后面(×)

如果将条件都写在on 后面,会发现王五这个用户信息没有了,王五只是没有地址,不应该他也被过滤掉

SELECT
    u.`name`,
    u.age,
    u.is_delete,
    a.address
FROM
    t_user u
    LEFT JOIN t_address a ON u.id = a.user_id
WHERE
    u.is_delete = 0
    AND a.is_delete = 0;

在这里插入图片描述
正确写法

在被left join的‘地址表’中的条件应该写在on后面

主表的条件应该写在where条件后面,如下:

SELECT
    u.`name`,
    u.age,
    u.is_delete,
    a.address
FROM
    t_user u
    LEFT JOIN t_address a ON u.id = a.user_id and a.is_delete = 0
WHERE
    u.is_delete = 0;

在这里插入图片描述
总结:

left join 进行表关联时,关联表(主表)的过滤条件放在where后面,被关联表(子表)的过滤条件放在on后面!

相关推荐

  1. 【数据库】PostgreSQLDISTINCT ONDISTINCT区别

    2024-07-10 16:04:06       53 阅读
  2. electronapp.whenReady()app.on(‘ready‘)区别

    2024-07-10 16:04:06       18 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-10 16:04:06       51 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-10 16:04:06       54 阅读
  3. 在Django里面运行非项目文件

    2024-07-10 16:04:06       44 阅读
  4. Python语言-面向对象

    2024-07-10 16:04:06       55 阅读

热门阅读

  1. linux从入门到精通

    2024-07-10 16:04:06       18 阅读
  2. 小程序-自定义导航栏

    2024-07-10 16:04:06       18 阅读
  3. Redis在项目中的17种使用场景

    2024-07-10 16:04:06       20 阅读
  4. 使用 Vue.js 和 Element Plus 实现自动完成搜索功能

    2024-07-10 16:04:06       21 阅读
  5. vue项目在window编译打包没问题linux编译打包报错

    2024-07-10 16:04:06       18 阅读
  6. vue 环境变量那些事

    2024-07-10 16:04:06       19 阅读
  7. R语言学习笔记5-数据结构-多维数组

    2024-07-10 16:04:06       20 阅读
  8. Mongodb地理信息数据查询

    2024-07-10 16:04:06       19 阅读
  9. uniapp实现图片懒加载 封装组件

    2024-07-10 16:04:06       25 阅读
  10. 有关区块链的一些数学知识储备

    2024-07-10 16:04:06       19 阅读
  11. MICCAI 2023 List of Papers

    2024-07-10 16:04:06       16 阅读