以下两个查询之间的差异是什么?两者都返回不同的行:
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 :(得分:0)
column1的排序在第一个查询中并没有真正做任何事情。
它按顺序创建一个结果集,但我不认为它会进入你的分区语句。 排序属于实际的分区子句。
答案 1 :(得分:0)
第一个版本对column1设置的整行进行排序,然后按column3对其进行分区并进行分析计算。请注意,column1的初始排序不一定通过分区保留 - 我认为这可能会让你感到困惑。
第二个版本按列3对数据进行分区,然后按列1对每个分区进行排序,然后确定分析输出。
答案 2 :(得分: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
之前实现,哈希或以任何其他方式毁掉ORDER BY
,因此CTE
中使用的{{1}}将会{因外部查询而丢失。