窗口可以與下面這些函數結合使用:sum(),avg(),max(),min(),count(),variance()和stddev();窗口也可以和first_value()與last_value()結合使用,這時候返回窗口中的第一個值和最後一個值。
先看下面列子
1 計算累計和
下面這個查詢通過執行累計和操作計算出2003年從一月到12月的累計銷量。注意每月的銷量都會加到累計值中,這樣累計和在每個月結束時都會增長
select month,
as cumulative_amount
order by month
結果集顯示如下:
id | month | month_amount | cumulative_amount |
1 | 1 | 95525.55 | 95525.55 |
2 | 2 | 116671.6 | 212197.15 |
3 | 3 | 160307.92 | 372505.07 |
4 | 4 | 175998.8 | 548503.87 |
5 | 5 | 154349.44 | 702853.31 |
6 | 6 | 124951.36 | 827804.67 |
7 | 7 | 170296.16 | 998100.83 |
8 | 8 | 212735.68 | 1210836.51 |
9 | 9 | 199609.68 | 1410446.19 |
10 | 10 | 264480.79 | 1674926.98 |
11 | 11 | 160221.98 | 1835148.96 |
12 | 12 | 137336.17 | 1972485.13 |
現在分析一下這個表達式
1 sum(amount) 計算出銷量的總和。外部的sum()計算累計銷量。
2 order by month按照月份對查詢讀取的記錄進行排序
3 rows between unbounded preceding and current row定義了窗口的行;窗口的終點是當前行。
rows between unbounded preceding and current row也可以是rows unbounded preceding
因此整個表達式的意思是從查詢讀取的第一行開始,計算每月的銷量的累計和
每次處理窗口的一行記錄時,都是從該窗口的第一條記錄開始。每一行記錄出來完之後,就將當前行的數量加到累計和中,並向下移動窗口的終點到下一行。然後繼續處理,直到查詢讀取的最後一行也被處理爲止。
下面這個查詢使用累計和來計算2003年6月到12月的累計銷量。注意使用rows unbounded preceding 來隱式地說明窗口的終點是當前行:
select month,
from all_sales
where year=2003
group by month
order by month
select month,
from all_sales
where year=2003
group by month
order by month
結果顯示
id | month | month_amount | moving_average |
1 | 1 | 95525.55 | 95525.55 |
2 | 2 | 116671.6 | 106098.575 |
3 | 3 | 160307.92 | 124168.3567 |
4 | 4 | 175998.8 | 137125.9675 |
5 | 5 | 154349.44 | 151831.94 |
6 | 6 | 124951.36 | 153901.88 |
7 | 7 | 170296.16 | 156398.94 |
8 | 8 | 212735.68 | 165583.16 |
9 | 9 | 199609.68 | 176898.22 |
10 | 10 | 264480.79 | 211780.5775 |
11 | 11 | 160221.98 | 209262.0325 |
12 | 12 | 137336.17 | 190412.155 |
現在分解一下這個表達式:
1sum(amount) 計算出銷量的總和。外部的avg()計算平均值
2 order by month按照月份對查詢讀出的記錄進行排序
3 rows between 3 preceding and current row定義了窗口的起點爲當前記錄的前面第三條記錄;窗口的終點爲當前記錄。也可以使用rows 3 preceding提前隱式的指定窗口大小,所得到的查詢結果完全相同。
因此,整個表達式的意思就是計算當前月份和此前三個月內的銷量移動平均值。由於最開始的兩個月可用的數據少於三個月,因此它們的移動平均值只是基於可用的月份計算的。
該窗口的起點和終點都是始於查詢讀取的的行#1;每次處理一行時,窗口的終點就向下移動。但是隻有當行#4處理完畢之後,窗口的起點才向下移動,從此之後,每當一條記錄處理完畢時,窗口的起點也會向下移動。整個過程一直持續到查詢讀取的最後一條記錄被處理爲止。
---------------------------------------------------------------------------
3 計算中心平均值
下面這個查詢計算當前月份前、後各一個月內的銷量移動平均值:
select month,
from all_sales
where year=2003
group by month
order by month
現在分析這個表達式
rows between 1 preceding and 1 following定義了窗口的起點是當前記錄之前的那條記錄。窗口的終點是當前記錄之後的那條記錄。
因此整個表達式的意思就是計算當前月、前一個月、後一個月的銷量移動平均值。由於第一個月和最後一個月可以參與計算的數據都少於三個月,因此移動平均值的計算只基於可用的數據。
---------------------------------------------------------------------------
4 用first_value()和last_value()獲取第一條記錄和最後一條記錄
first_value()和last_value()函數可以獲取第一行和最後一行的數據。下面這個查詢用first_value()和last_value()獲取前一個月和最後一個月的銷量:
select month,
last_value(sum(amount)) over (order by month rows between 1 preceding and 1 following) as next_month_amount
from all_sales
where year=2003
group by month
order by month
結果集:
id | month | month_amount | previous_month_amount | next_month_amount |
1 | 1 | 95525.55 | 95525.55 | 116671.6 |
2 | 2 | 116671.6 | 95525.55 | 160307.92 |
3 | 3 | 160307.92 | 116671.6 | 175998.8 |
4 | 4 | 175998.8 | 160307.92 | 154349.44 |
5 | 5 | 154349.44 | 175998.8 | 124951.36 |
6 | 6 | 124951.36 | 1154349.44 | 170296.16 |
7 | 7 | 170296.16 | 124951.36 | 212735.68 |
8 | 8 | 212735.68 | 1170296.16 | 199609.68 |
9 | 9 | 199609.68 | 2212735.68 | 264480.79 |
10 | 10 | 264480.79 | 199609.68 | 160221.98 |
11 | 11 | 160221.98 | 264480.79 | 137336.17 |
12 | 12 | 137336.17 | 160221.98 | 137336.17 |
下面這個查詢將當前月份的銷量除以前一個月的銷量(保存在curr_div_prev列中),並將當前月份的銷量除以下一個月的銷量(保存在curr_dive_next列中):
select month,
sum(amount)/last_value(sum(amount)) over (order by month rows between 1 preceding and 1 following) as curr_div_next
from all_sales
where year=2003
group by month
order by month
id | month | month_amount | curr_div_prev | curr_div_next |
1 | 1 | 95525.55 | 1 | 0.818755807 |
2 | 2 | 116671.6 | 1.221365383 | 0.727796855 |
3 | 3 | 160307.92 | 1.374009785 | 0.910846665 |
4 | 4 | 175998.8 | 1.097879631 | 1.140261993 |
5 | 5 | 154349.44 | 0.876991434 | 1.235276191 |
6 | 6 | 124951.36 | 0.809535558 | 0.733729756 |
7 | 7 | 170296.16 | 1.362899611 | 0.800505867 |
8 | 8 | 212735.68 | 1.249210082 | 1.065758334 |
9 | 9 | 199609.68 | 0.93829902 | 0.754722791 |
10 | 10 | 264480.79 | 1.3249898 | 1.650714777 |
11 | 11 | 160221.98 | 0.605798175 | 1.166640806 |
12 | 12 | 137336.17 | 0.857161858 | 1 |
轉載:http://blog.chinaunix.net/uid-7450061-id-2054536.html