文章目录
- 一、初始数据
- 二、问题分析
- 三、总结
先说结论,
1.如果想要拿到主表不受到关联表查询条件的数据的话,那么建议直接将查询条件放到on之后。
2.如果将关联表的条件查询放在where之后,可能会将主表中的数据进行排除。
所以如果想实现的查询是通过关联表的条件过滤主表的记录时,则可以在where后添加查询条件。
3.如果只是想要确保sys_station_system表中的记录满足deleted = 0,则可以在join on后添加查询条件。
一、初始数据
sys_station表
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for sys_station
-- ----------------------------
DROP TABLE IF EXISTS `sys_station`;
CREATE TABLE `sys_station` (
`id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
`name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '站点名称',
`deleted` tinyint(1) NULL DEFAULT 0,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '站点表' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of sys_station
-- ----------------------------
INSERT INTO `sys_station` VALUES ('1', 'test1', 0);
INSERT INTO `sys_station` VALUES ('2', 'test2', 0);
INSERT INTO `sys_station` VALUES ('3', 'test3', 0);
SET FOREIGN_KEY_CHECKS = 1;
sys_station_system表
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for sys_station_system
-- ----------------------------
DROP TABLE IF EXISTS `sys_station_system`;
CREATE TABLE `sys_station_system` (
`id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
`system_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '所属系统id',
`station_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '站点id',
`deleted` tinyint(1) NULL DEFAULT 0,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '站点系统关联表' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of sys_station_system
-- ----------------------------
INSERT INTO `sys_station_system` VALUES ('1', '1', '1', 0);
INSERT INTO `sys_station_system` VALUES ('2', '1', '2', 1);
INSERT INTO `sys_station_system` VALUES ('3', '1', '2', 0);
INSERT INTO `sys_station_system` VALUES ('4', '1', '3', 1);
SET FOREIGN_KEY_CHECKS = 1;
二、问题分析
首选直接进行关联查询,会返回所有关联数据
SELECT s.id,s.name,ss.id joinId
FROM sys_station s
LEFT JOIN sys_station_system ss ON s.id = ss.station_id
WHERE s.deleted = 0;
1.此时在where后加上关联表的查询条件
SELECT s.id,s.name,ss.id joinId
FROM sys_station s
LEFT JOIN sys_station_system ss ON s.id = ss.station_id
WHERE s.deleted = 0 AND ss.deleted = 0;
这条sql查询首先执行LEFT JOIN,将sys_station表和sys_station_system表连接起来,基于s.id和ss.station_id的匹配。之后,在WHERE子句中过滤结果,只保留那些sys_station表中deleted=0和sys_station_system表中deleted=0的记录。这意味着,如果sys_station_system表中对应的某个sys_station的记录deleted不等于0,那么这条记录将不会被包含在最终的结果集中。
关联表的条件写在where后可能会影响到主表的数据显示,当使用left join时慎用!
2.在关联表后加查询条件
SELECT s.id,s.name,ss.id joinId
FROM sys_station s
LEFT JOIN sys_station_system ss ON s.id = ss.station_id AND ss.deleted = 0
WHERE s.deleted = 0;
这条查询在LEFT JOIN子句中包含了ss.deleted = 0的条件,这意味着在连接操作时就会排除那些sys_station_system表中deleted字段不等于0的记录。因此,只有当sys_station_system表中deleted字段为0的记录才会被加入到连接的结果中。
三、总结
1.当使用left join时慎用第一条sql(where后加关联表的查询条件)
2.如果想实现的查询是通过关联表的条件过滤主表的记录时,则可以在where后添加查询条件。
3.如果只是想要确保sys_station_system表中的记录满足deleted = 0,则可以在join on后添加查询条件。