求助 先 where条件过滤 还是先 join on

时间:2021-03-13 22:32:07
 oracle  在做多表关联查询的时候 是先 进行 where 条件的过滤 还是先进行 表之间的连接呢。
 一直以来 我都 认为 是要先进行 where 过滤之后 才进行表之间的关联的。然而今天做了一个实验 
 测试数据如下。
WITH TEMP_TAB1 AS 
(
  SELECT 1 ID , 'MINGMING' NAME ,0 SCORE FROM DUAL UNION ALL 
   SELECT 9 ID , 'MINGMING' NAME ,20 SCORE FROM DUAL UNION ALL 
  SELECT 2 ID , 'HUAHUA' NAME , 80 SCORE FROM DUAL UNION ALL 
  SELECT 3 ID , 'NIUNIU' NAME, 90 SCORE FROM DUAL UNION ALL 
  SELECT 4 ID , 'MEI' NAME ,70 SCORE FROM DUAL UNION ALL 
  SELECT 5 ID , 'YOU' NAME, 40 SCORE FROM DUAL 
) ,TEMP_TAB2 AS 
(
  SELECT 1 ID , 'REN' NAME , 20 SCORE FROM DUAL UNION ALL 
  SELECT 3 ID , 'NIUNIU'  NAME ,30 SCORE FROM DUAL UNION ALL  
  SELECT 4 ID , 'RURU'  NAME ,60 SCORE FROM DUAL UNION ALL 
  SELECT 5 ID , 'HONGHONG'  NAME ,0 SCORE FROM DUAL 
) SELECT *
  FROM TEMP_TAB1 A 
 inner JOIN TEMP_TAB2 B 
 ON A.ID = B.ID 
 and b.score <> 0 
 --and 10/a.score = 0.25 
 where 10/b.score = 0.5  

如果先执行 where后面的条件 在执行 on 的话 应该会报错的。但是现在没有报错。 那是不是 说明 先执行表之间的关联等关联出结果之后 在进行where条件过滤

7 个解决方案

#1


oracle执行顺序,从右往左,从下而上。根据你上面的理解,我认为你错了。--个人看法
上面的语句完全用不着where关键字,直接and。
另where左边的计算移到右边。

本人的理解分析--仅供参考
1、执行它 10/b.score = 0.5 结果 b.score =20 过滤不是20的数据,b表只有id=1符合
2、执行 b.score <> 0 依然只有id=1
3、执行 A.ID = B.ID id=1的a表只有一条
--结果表a id=1的数据和表b id=1的数据展示。

#2


引用 1 楼  的回复:
oracle执行顺序,从右往左,从下而上。根据你上面的理解,我认为你错了。--个人看法
上面的语句完全用不着where关键字,直接and。
另where左边的计算移到右边。

本人的理解分析--仅供参考
1、执行它 10/b.score = 0.5 结果 b.score =20 过滤不是20的数据,b表只有id=1符合
2、执行 b.score <> 0 依然只有id=1
3、执行……
  按照你的说法 如果 将 and b.score <> 0 条件去掉的话,  
(1、执行它 10/b.score = 0.5 结果 b.score =20 过滤不是20的数据,b表只有id=1符合 )
这个条件 就已经过滤 了 = 0 结果 就不会报错了。但是 去掉之后 是报错了。

 

#3



SQL Select语句完整的执行顺序: 

1、from子句组装来自不同数据源的数据;
2、where子句基于指定的条件对记录行进行筛选;
3、group by子句将数据划分为多个分组;
4、使用聚集函数进行计算;
5、使用having子句筛选分组;
6、计算所有的表达式;
7、select 的字段;
8、使用order by对结果集进行排序。

#4


引用 3 楼  的回复:
SQL code

SQL Select语句完整的执行顺序: 

1、from子句组装来自不同数据源的数据;
2、where子句基于指定的条件对记录行进行筛选;
3、group by子句将数据划分为多个分组;
4、使用聚集函数进行计算;
5、使用having子句筛选分组;
6、计算所有的表达式;
7、select 的字段;
8、使用order by对结果集进行排序。

谢谢你的回答。
  那么 就是先执行 from 子句中表之间的关联了,然后再执行 where条件过滤。
  
  如果用标准写法的话 ,过滤条件加在on之后 会 先 where之后的条件 执行 。

   


#5


引用 3 楼  的回复:
SQL code


SQL Select语句完整的执行顺序: 

1、from子句组装来自不同数据源的数据;
2、where子句基于指定的条件对记录行进行筛选;
3、group by子句将数据划分为多个分组;
4、使用聚集函数进行计算;
5、使用having子句筛选分组;
6、计算所有的表达式;
7、select 的字段;
8、使用order by对结果集进行排序。

……


这样是对的

#6


引用 5 楼  的回复:
引用 3 楼  的回复:
SQL code


SQL Select语句完整的执行顺序:

1、from子句组装来自不同数据源的数据;
2、where子句基于指定的条件对记录行进行筛选;
3、group by子句将数据划分为多个分组;
4、使用聚集函数进行计算;
5、使用having子句筛选分组;
6、计算所有的表达式;
7、select 的字段;
8、使用order ……


  如果 我sql 这么写 
   select * from a inner join b on a.id = b.id 
   where a.date = 20120807 
     and b.date = 20120807 
  岂不是要先 进行 a表与b表之间的关联啦。 那表就太大了啊。应该先过滤 再关联的啊。
   类似的语句 通常 都是将date的条件加where之后的。请问原因?
   

#7


inner join、join left 比条件筛选效率要高很多

#1


oracle执行顺序,从右往左,从下而上。根据你上面的理解,我认为你错了。--个人看法
上面的语句完全用不着where关键字,直接and。
另where左边的计算移到右边。

本人的理解分析--仅供参考
1、执行它 10/b.score = 0.5 结果 b.score =20 过滤不是20的数据,b表只有id=1符合
2、执行 b.score <> 0 依然只有id=1
3、执行 A.ID = B.ID id=1的a表只有一条
--结果表a id=1的数据和表b id=1的数据展示。

#2


引用 1 楼  的回复:
oracle执行顺序,从右往左,从下而上。根据你上面的理解,我认为你错了。--个人看法
上面的语句完全用不着where关键字,直接and。
另where左边的计算移到右边。

本人的理解分析--仅供参考
1、执行它 10/b.score = 0.5 结果 b.score =20 过滤不是20的数据,b表只有id=1符合
2、执行 b.score <> 0 依然只有id=1
3、执行……
  按照你的说法 如果 将 and b.score <> 0 条件去掉的话,  
(1、执行它 10/b.score = 0.5 结果 b.score =20 过滤不是20的数据,b表只有id=1符合 )
这个条件 就已经过滤 了 = 0 结果 就不会报错了。但是 去掉之后 是报错了。

 

#3



SQL Select语句完整的执行顺序: 

1、from子句组装来自不同数据源的数据;
2、where子句基于指定的条件对记录行进行筛选;
3、group by子句将数据划分为多个分组;
4、使用聚集函数进行计算;
5、使用having子句筛选分组;
6、计算所有的表达式;
7、select 的字段;
8、使用order by对结果集进行排序。

#4


引用 3 楼  的回复:
SQL code

SQL Select语句完整的执行顺序: 

1、from子句组装来自不同数据源的数据;
2、where子句基于指定的条件对记录行进行筛选;
3、group by子句将数据划分为多个分组;
4、使用聚集函数进行计算;
5、使用having子句筛选分组;
6、计算所有的表达式;
7、select 的字段;
8、使用order by对结果集进行排序。

谢谢你的回答。
  那么 就是先执行 from 子句中表之间的关联了,然后再执行 where条件过滤。
  
  如果用标准写法的话 ,过滤条件加在on之后 会 先 where之后的条件 执行 。

   


#5


引用 3 楼  的回复:
SQL code


SQL Select语句完整的执行顺序: 

1、from子句组装来自不同数据源的数据;
2、where子句基于指定的条件对记录行进行筛选;
3、group by子句将数据划分为多个分组;
4、使用聚集函数进行计算;
5、使用having子句筛选分组;
6、计算所有的表达式;
7、select 的字段;
8、使用order by对结果集进行排序。

……


这样是对的

#6


引用 5 楼  的回复:
引用 3 楼  的回复:
SQL code


SQL Select语句完整的执行顺序:

1、from子句组装来自不同数据源的数据;
2、where子句基于指定的条件对记录行进行筛选;
3、group by子句将数据划分为多个分组;
4、使用聚集函数进行计算;
5、使用having子句筛选分组;
6、计算所有的表达式;
7、select 的字段;
8、使用order ……


  如果 我sql 这么写 
   select * from a inner join b on a.id = b.id 
   where a.date = 20120807 
     and b.date = 20120807 
  岂不是要先 进行 a表与b表之间的关联啦。 那表就太大了啊。应该先过滤 再关联的啊。
   类似的语句 通常 都是将date的条件加where之后的。请问原因?
   

#7


inner join、join left 比条件筛选效率要高很多