摘自:http://cqujsjcyj.iteye.com/blog/952302
http://jackleechina.iteye.com/blog/2087856
运行平台:PostgreSQL
目的:比较join......on 后面的and 和where的区别
数据库在通过连接两张或多张表来返回记录时,都会生成一张中间的临时表,然后再将这张临时表返回给用户。
1)建tab1表
-- ----------------------------
-- Table structure for tab1
-- ----------------------------
DROP TABLE IF EXISTS "public"."tab1";
CREATE TABLE "public"."tab1" (
"id" int4 NOT NULL,
"size" int4
)
WITH (OIDS=FALSE)
;
添加数据
-- ----------------------------
-- Records of tab1
-- ----------------------------
INSERT INTO "public"."tab1" VALUES ('1', '10');
INSERT INTO "public"."tab1" VALUES ('2', '20');
INSERT INTO "public"."tab1" VALUES ('3', '30');
-- ----------------------------
-- Alter Sequences Owned By
-- ----------------------------
-- ----------------------------
-- Primary Key structure for table tab1
-- ----------------------------
ALTER TABLE "public"."tab1" ADD PRIMARY KEY ("id");
2)建tab2表
-- ----------------------------
-- Table structure for tab2
-- ----------------------------
DROP TABLE IF EXISTS "public"."tab2";
CREATE TABLE "public"."tab2" (
"size" int4,
"name" varchar(32) COLLATE "default"
)
WITH (OIDS=FALSE)
;
添加数据
-- ----------------------------
-- Records of tab2
-- ----------------------------
INSERT INTO "public"."tab2" VALUES ('10', 'AAA');
INSERT INTO "public"."tab2" VALUES ('20', 'BBB');
INSERT INTO "public"."tab2" VALUES ('20', 'CCC');
3)比较下面的运行结果
两条SQL:
1、select * form tab1 left join tab2 on (tab1.size = tab2.size) where tab2.name=’AAA’
2、select * form tab1 left join tab2 on (tab1.size = tab2.size and tab2.name=’AAA’)
第一条SQL的过程:
1、中间表
on条件:
tab1.size = tab2.size
tab1.id tab1.size tab2.size tab2.name
1 10 10 AAA
2 20 20 BBB
2 20 20 CCC
3 30 (null) (null)
2、再对中间表过滤
where 条件:
tab2.name=’AAA’
tab1.id tab1.size tab2.size tab2.name
1 10 10 AAA
第二条SQL的过程:
1、中间表
on条件:
tab1.size = tab2.size and tab2.name=’AAA’
(条件不为真也会返回左表中的记录)
tab1.id tab1.size tab2.size tab2.name
1 10 10 AAA
2 20 (null) (null)
3 30 (null) (null)



4)结论
4.1) where 是在两个表join完成后,再附上where条件。
4.2)
而 and 则是在表连接前过滤A表或B表里面哪些记录符合连接条件,同时会兼顾是left join还是right join。即
假如是左连接的话①如果左边表的某条记录不符合连接条件,那么它不进行连接,但是仍然留在结果集中(此时右边部分的连接结果为NULL)。
②如果右边表的某条记录不符合连接条件,那么它不进行连接。
4.3)建议尽量用where来过滤条件,以避免复杂的逻辑考虑。(除非在某些情况下(后接其他sql语句),用where会报错,才用and,但要考虑是否影响正确结果。)
浙公网安备 33010602011771号