首先说下结论:链接查询,如果on条件是非唯一字段,会出现笛卡尔积(局部笛卡尔积);如果on条件是表的唯一字段,则不会出现笛卡尔积。
测试大法:
首先构建两张表,一张用户表(5条数据)、一张工作部门表(4条数据)。
CREATE TABLE `user` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`addr` varchar(255) DEFAULT NULL,
`email` varchar(255) DEFAULT NULL,
`job_id` int DEFAULT NULL,
`valid` int DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `index_name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb3;
INSERT INTO `user` VALUES (1, 'zhangsan', 'hangzhou', 'dafaa', 1, 1);
INSERT INTO `user` VALUES (2, 'list', 'lisi', 'dfdaff', 2, 1);
INSERT INTO `user` VALUES (3, '王五', 'ahngzhou', 'ddd', 3, 1);
INSERT INTO `user` VALUES (4, '赵六', '哈哈', 'ddd', 4, 1);
INSERT INTO `user` VALUES (5, '孙启', '呵呵', 'ff', 1, 1);
DROP TABLE IF EXISTS `job`;
CREATE TABLE `job` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`valid` int DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb3;
-- ----------------------------
-- Records of job
-- ----------------------------
BEGIN;
INSERT INTO `job` VALUES (1, '产品部', 1);
INSERT INTO `job` VALUES (2, '技术部', 1);
INSERT INTO `job` VALUES (3, '财务部', 1);
INSERT INTO `job` VALUES (4, '人事部', 1);
COMMIT;
SET FOREIGN_KEY_CHECKS = 1;
SELECT * from user,job;
结论:交叉连接,会产生笛卡尔积。
内连接
内连接唯一字段
SELECT
*
FROM
`user` u
JOIN job j ON u.job_id = j.id;
结论:内连接查询,on条件是两张表的唯一字段,不会产生笛卡尔积。
内连接非唯一字段
如果A表有m条记录,m1条符合on条件,B表有n条记录,有n1条符合on条件,则结果集是m1*n1
SELECT
*
FROM
`user` u
JOIN job j ON u.valid = j.valid;
外连接
左连接
左连接唯一字段
假如A表有m条记录,B表有n条记录,则结果集是m条。
左连接非唯一字段。
加入A表有m条符合条件的记录,B表有n条记录,则结果集是m*n条记录。
右连接也是一样的逻辑。