2017-06-05 20 views
1

私は指定されたパーティションの1つの列の最初の値と2番目の列の最後の値を1つの行に入れたいと思います。そのために私はこのクエリ作成:PostgreSQLの1行のウィンドウ関数の最初と最後の値

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になります。

UNBOUNDED PRECEDINGのframe_startは、フレームがパーティションの最初の行で始まり、同様にUNBOUNDED FOLLOWINGの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_valuemax()に置き換えてください。 timestamp_staでソートしていますので、最後の値はtimestamp_staで、timestamp_stpに関連する場合とそうでない場合があります。また、私は2つのフィールドでソートします。

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

関連する問題