下面的查询给出了奇怪的结果。看起来,FIRST_VALUE的默认窗口始终是无界的,而LAST_VALUE的默认窗口与CURRENT_ROW和CURRENT_ROW类似。为什么会这样呢?
select
to_char(INVOICEDATE,'iw') WEEK,
SUM(total) AS TOTAL_SUM,
FIRST_VALUE(to_char(INVOICEDATE,'iw')) OVER (order by SUM(total)) minimum,
FIRST_VALUE(to_char(INVOICEDATE,'iw')) OVER (order by SUM(total) DESC) maximum,
LAST_VALUE(to_char(INVOICEDATE,'iw')) OVER (order by SUM(total)) max_2,
LAST_VALUE(to_char(INVOICEDATE,'iw')) OVER (order by SUM(total) ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) max_3
from invoice
WHERE to_char(INVOICEDATE,'iw') < 9
group by to_char(INVOICEDATE,'iw')
order by to_char(INVOICEDATE,'iw')
这里的结果是:
发布于 2018-03-29 03:37:57
噢,我现在明白了。这两个函数的窗口都类似于前面和当前行的无界窗口,但是FIRST_VALUE得到了第一行,因此无论跟随多少行,它总是显示第一个结果,而LAST_VALUE总是显示CURRENT_ROW。谢谢大家!
发布于 2018-03-29 03:46:16
如果一次查看一个计算列,并命令输出与over
子句排序相匹配,您可能会发现更容易跟踪正在发生的事情。
只适用于第一值最小值,按总数排序:
select
to_char(invoicedate,'iw') week,
sum(total) as total_sum,
first_value(to_char(invoicedate,'iw')) over (order by sum(total)) minimum
from invoice
where to_char(invoicedate,'iw') < 9
group by to_char(invoicedate,'iw')
order by total_sum;
WEEK TOTAL_SUM MINIMUM
---- ---------- -------
08 30.7 08
04 34.65 08
01 35.65 08
03 38.66 08
05 41.58 08
06 56.43 08
07 59.48 08
02 63.45 08
您所使用的排序(在over()
中)意味着由first_value
处理的第一行是08,因此它看到了自己。排序中的第二行是week 04,但是它考虑了行unbounded preceding to current row
,所以它看了08和04,并且接受08,因为它仍然是(并且总是按照这个顺序)。诸若此类。
对于第一个值最大值,按总降序排序:
select
to_char(invoicedate,'iw') week,
sum(total) as total_sum,
first_value(to_char(invoicedate,'iw')) over (order by sum(total) desc) maximum
from invoice
where to_char(invoicedate,'iw') < 9
group by to_char(invoicedate,'iw')
order by total_sum desc;
WEEK TOTAL_SUM MAXIMUM
---- ---------- -------
02 63.45 02
07 59.48 02
06 56.43 02
05 41.58 02
03 38.66 02
01 35.65 02
04 34.65 02
08 30.7 02
这与前一个相反;使用该顺序的第一行用于第02周;第二行考虑02和07,并使用02,因为这仍然是(并且始终是通过该排序)。
对于最后一个值最大值,按总数排序:
select
to_char(invoicedate,'iw') week,
sum(total) as total_sum,
last_value(to_char(invoicedate,'iw')) over (order by sum(total)) max_2
from invoice
where to_char(invoicedate,'iw') < 9
group by to_char(invoicedate,'iw')
order by total_sum;
WEEK TOTAL_SUM MAX_2
---- ---------- -------
08 30.7 08
04 34.65 04
01 35.65 01
03 38.66 03
05 41.58 05
06 56.43 06
07 59.48 07
02 63.45 02
现在,行被按与前一个块不同的顺序考虑。排序的第一行返回到08,我们仍然使用默认的window子句,因此只能使用该子句。
第二行是第04周,只能考虑08和04;按照顺序04现在是最后看到的值。对于随后的所有行,这是相同的;最后看到的值是该行,这是因为排序。
窗口是相同的,但是您使用的排序会影响该窗口中的实际行。对于max_3
计算,您将更改窗口以包含所有行;您还可以反转默认窗口,使其(实际上)与用于first_rows
的窗口匹配。
last_value(to_char(invoicedate,'iw')) over (order by sum(total)
rows between current row and unbounded following) max_3
https://stackoverflow.com/questions/49554572
复制相似问题