1. 程式人生 > >PostgreSQL中的視窗函式

PostgreSQL中的視窗函式

PostgreSQL中提供了視窗函式,一個視窗函式在一系列與當前行有某種關聯的錶行上進行一種計算。
一個視窗函式呼叫總是包含一個直接跟在視窗函式名及其引數之後的OVER子句。OVER子句決定究竟查詢中的哪些行被分離出來由視窗函式處理。對於每一行,視窗函式都會在當前行同一分割槽的行上進行計算。
另一個與視窗函式相關的重要概念是:對於每一行,在它的分割槽中的行集被稱為視窗幀。 許多視窗函式只作用在視窗幀中的行上,而不是整個分割槽。預設情況下,如果使用ORDER BY,則幀包括從分割槽開始到當前行的所有行,以及任何根據ORDER BY子句和當前行相等的後續行。如果ORDER BY被忽略,則預設幀包含分割槽中的所有行。
舉個例子,新建一個表wdtest,插入一些資料:
這裡寫圖片描述


如果我們忽略ORDER BY,結果如下:
這裡寫圖片描述
由於在OVER子句中沒有ORDER BY,視窗幀就會和分割槽一樣。換句話說,每個sum()都會在整個表上進行,這樣每個輸出行得到的結果相同。但是如果在OVER子句中加上一個ORDER BY子句,結果就會不同:
這裡寫圖片描述
這裡的sum()是從第一個(最低的)值一直到當前行,包括任何與當前行相同的行。這裡需要注意的是有相同值的行的結果。
在一個查詢中可以包含多個視窗函式,每個視窗函式都可以用不同的OVER子句來按不同方式劃分資料,但是它們都作用在由虛擬表定義的同一個行集上。
舉例如下:
這裡寫圖片描述
這個例子中我們分別檢視資料集中正序和倒序排列的第一個值。
然而,如果我們稍作改動,檢視last_value,會產生令人意外的結果:
這裡寫圖片描述

從結果中可以看到,這兩列都返回相同的資料,不管ORDER BY子句中的不同排列順序要求。
我們可以通過array_agg函式來看last_value真正的返回值是怎麼得出的。
這裡寫圖片描述
array_agg會簡單的把它們都放到一個數組中。所以這兩種情況下陣列中的last value值是完全一致的,從而導致上述現象的發生。

By Kalath