一、SQL環境準備
首先創建兩個表,並插入基本數據:
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`username` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`age` int(11) NULL DEFAULT NULL,
`sex` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES ('1', 'tony', 20, '1');
INSERT INTO `user` VALUES ('2', 'jack', 21, '1');
INSERT INTO `user` VALUES ('3', 'lisa', 22, '1');
INSERT INTO `user` VALUES ('4', 'tom', 19, '1');
INSERT INTO `user` VALUES ('5', 'anmy', 20, '1');
INSERT INTO `user` VALUES ('6', 'bobo', 21, '1');
-- ----------------------------
-- Table structure for user_address
-- ----------------------------
DROP TABLE IF EXISTS `user_address`;
CREATE TABLE `user_address` (
`id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`user_id` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`address` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of user_address
-- ----------------------------
INSERT INTO `user_address` VALUES ('A', '1', '廣州');
INSERT INTO `user_address` VALUES ('B', '2', '深圳');
INSERT INTO `user_address` VALUES ('C', '3', '杭州');
INSERT INTO `user_address` VALUES ('D', '4', '上海');
INSERT INTO `user_address` VALUES ('E', '5', '北京');
INSERT INTO `user_address` VALUES ('F', '6', '湛江');
SET FOREIGN_KEY_CHECKS = 1;
二、查詢
2.1 使用left join查詢用戶爲“tony”以及該用戶地址信息(where 方式過濾):
SELECT * FROM user u LEFT JOIN user_address ua ON u.id = ua.user_id WHERE u.username = 'tony';
查詢到的結果如圖:
2.2 使用left join查詢用戶爲“tony”以及該用戶地址信息(and 方式過濾):
SELECT * FROM user u LEFT JOIN user_address ua ON u.id = ua.user_id AND u.username = 'tony';
查詢到的結果如下圖:
可見,兩種方式的查詢結果截然不同,正確的結果應該是隻查詢名字爲“tony” 的用戶和地址信息,預期結果只返回一條,使用and方式查詢,雖然也把該用戶的信息查詢出來了,但是其他用戶的信息也查詢出來了,不符合預期!
三、原理分析
通過上述在left join on後使用and或where的演示,分析如下:
- and 條件是在生成臨時表時使用的條件,不管條件是否爲真,都會返回左邊表中的記錄,適用於查詢左表的所有數據的情況。
- where 條件是在臨時表生成好後,再對臨時表進行過濾的條件,條件爲真時纔會返回左表中的記錄。適用於查詢左表中符合條件的數據的情況。
left join,right join,full join的特殊性和left join是類似的,而inner join沒有這個特性。