2009-08-04 42 views
1

以下两个查询之间的区别是什么?双方将返回不同的行:两个分析查询之间的差异

with ordered_table as 
(
select * from table order by column1 
) 
select first_value(column2 ignore nulls) over (partition by column3) 
from ordered_table; 

select first_value(column2 ignore nulls) over (partition by column3 order by column1) 
from table; 

注:我会尽力提供一个测试用例,但我认为,一个人有明确的不需要的概念。

回答

0
WITH ordered_table AS 
     (
     SELECT * 
     FROM table 
     ORDER BY 
       column1 
     ) 
SELECT FIRST_VALUE(column2 IGNORE NULLS) OVER (PARTITION BY column3) 
FROM ordered_table 

这个查询将在没有特定的顺序返回column2第一每个分区的值(即在CBO可以自由选择它认为最好的任何顺序)。

SELECT FIRST_VALUE(column2 IGNORE NULLS) OVER (PARTITION BY column3 ORDER BY column1) 
FROM table; 

这个查询将返回的column2第一每个分区的值,来column1订购分区。

由于SQL语言上套工作,和你的ORDER BY条款不做任何处理的CTE返回的集合中,Oracle只是忽略ORDER BY部分。

CBO可以选择兑现,散列或以任何其他方式切去CTE它是由外部查询使用之前,所以在CTE使用的ORDER BY将失去外部查询。

0

第1列的排序在第一个查询中没有做任何事情。

它按顺序创建一个结果集,但我认为这不会影响您的分区声明。 该排序属于实际的分区条款。

0

第一个版本对column1设置的整个行进行排序,然后将其按column3进行分区并进行分析计算。请注意,第一列的初始排序不一定通过分区保留 - 我认为这可能会让你感到困扰。

第二个版本按column3分区数据,然后按column1对每个分区进行排序,然后确定分析输出。