SQL語句查詢 LEFT JOIN 後用 ON 還是 WHERE 的區別?

一、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沒有這個特性。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章