FIRST_VALUE和LAST_VALUE的不同数据窗口

时间:2018-03-29 11:10:14

标签: sql oracle

以下查询给出了奇怪的结果。看起来FIRST_VALUE的默认窗口始终是UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING,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')

结果如下:

HERE ARE THE RESULST

2 个答案:

答案 0 :(得分:1)

哦,我现在明白了。 这两个函数都有像UNBOUNDED PRECEDING和CURRENT ROW这样的窗口,但是FIRST_VALUE得到第一行,所以无论它跟随多少,它总是显示第一个结果,而LAST_VALUE总是显示CURRENT_ROW。 谢谢大家!

答案 1 :(得分:1)

如果您一次查看一个计算列,并且命令输出与function printGame(){ var html = ""; html+='<table>'; for (var i = 0; i < 3; i++) { // add opening <tr> tag to the string: html += '<tr id="'+i+'">'; for (var j = 0; j < 3; j++) { // add <td> elements to the string: html += '<td id="'+j+'">' + '${applicationScope.tableStatus[0][0]}' + '</td>'; } // add closing </tr> tag to the string: html += '</tr>'; } html+='</table>'; return html; 子句排序匹配,您可能会发现更容易理解发生的情况。

仅限第一个最小值,按总数排序:

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()处理的第一行是08,因此它会看到自己。该排序中的第二行是第04周,但是它考虑了行first_value,所以它看起来是08和04,并且因为它仍然是(因为那个顺序),所以需要08。等等。

仅对于第一个值的最大值,按总降序排序:

unbounded preceding to current row

这与前一个相反;使用该订单看到的第一行是第02周;第二行考虑02和07并使用02,因为它仍然是(并且总是按照那个顺序)。

仅限最后一个值,按总数排序:

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     

现在,行的行数与前一个块的顺序不同。具有该排序的第一行返回到08,并且我们仍然使用默认窗口子句,因此只能使用该子句。

第二行是第04周,只能考虑08和04;和按顺序 04现在是最后看到的值。对于所有后续行,这是相同的;看到的最后一个值是那行,因为有序。

窗口是相同的,但您使用的顺序会影响该窗口中实际存在的行。对于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 计算,您要更改窗口以包含所有行;你也可以反转默认窗口,以便它(有效地)匹配用于max_3的窗口:

first_rows