2017-06-05 75 views
1

我想爲一個指定的分區在一行中的第一列的第一個值和第二列的最後一個值。爲此,我創建了此查詢:PostgreSQL中的一行中的窗函數的第一個和最後一個值

SELECT DISTINCT 
b.machine_id, 
batch, 
timestamp_sta, 
timestamp_stp, 
FIRST_VALUE(timestamp_sta) OVER w AS batch_start, 
LAST_VALUE(timestamp_stp) OVER w AS batch_end 
FROM db_data.sta_stp AS a 
JOIN db_data.ll_lu AS b 
ON a.ll_lu_id=b.id 
WINDOW w AS (PARTITION BY batch, machine_id ORDER BY timestamp_sta) 
ORDER BY timestamp_sta, batch, machine_id; 

但正如您在圖像中看到的,batch_end列中返回的數據不正確。

batch_start列有正確的第一個值timestamp_sta列。但batch_end應該是「2012-09-17 10:49:45」,它等於timestamp_stp來自同一行。

這是爲什麼?

enter image description here

回答

3

syntax documentation

的frame_clause指定一組構成窗框,這是當前分區的子集的行的,用於該幀,而不是在充當那些窗口函數整個分區。該框架可以在RANGE或ROWS模式下指定;無論哪種情況,它都從frame_start運行到frame_end。 如果省略frame_end,則默認爲CURRENT ROW

無界前接的frame_start意味着該幀以該分區的第一行開始,並且類似地,未結束後的frame_end意味着該幀以該分區的最後一行結束。

function list

LAST_VALUE(任何價值)返回的行計算值是窗框的最後一排

所以正確的SQL應該是:

SELECT DISTINCT 
b.machine_id, 
batch, 
timestamp_sta, 
timestamp_stp, 
FIRST_VALUE(timestamp_sta) OVER w AS batch_start, 
LAST_VALUE(timestamp_stp) OVER w AS batch_end 
FROM db_data.sta_stp AS a 
JOIN db_data.ll_lu AS b 
ON a.ll_lu_id=b.id 
WINDOW w AS (PARTITION BY batch, machine_id ORDER BY timestamp_sta range between unbounded preceding and unbounded following) 
ORDER BY timestamp_sta, batch, machine_id; 
+0

大,這就是它!我剛剛發現了這個手冊頁,但我仍然不完全明白它的工作原理。感謝您的工作示例。 –

+1

不幸的是,我不認爲它會返回預期的結果。 – klin

+0

@klin是的,它爲我做了。這個解決方案有什麼問題? –

3

由@英鎊給出的解釋ukaszKamiński解決問題的核心。

但是,last_value應替換爲max()。您按timestamp_sta排序,因此最後一個值是timestamp_sta的最大值,它可能與timestamp_stp有關,也可能不相關。我也會根據這兩個領域進行排序。

SELECT DISTINCT 
    b.machine_id, 
    batch, 
    timestamp_sta, 
    timestamp_stp, 
    FIRST_VALUE(timestamp_sta) OVER w AS batch_start, 
    MAX(timestamp_stp) OVER w AS batch_end 
FROM db_data.sta_stp AS a 
JOIN db_data.ll_lu AS b 
ON a.ll_lu_id=b.id 
WINDOW w AS (PARTITION BY batch, machine_id 
      ORDER BY timestamp_sta,timestamp_stp 
      RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) 
ORDER BY timestamp_sta, batch, machine_id; 

http://rextester.com/UTDE60342

相關問題