2016-11-18 19 views
0

2つの列を持つ次の表があります。PostgreSQL:各ID列に最初に挿入されたレコードと最後に挿入されたレコードを取得します。

create table tbl1 
(
    p_id int, 
    p_price int 
); 

挿入

INSERT INTO tbl1 values(1,100); 
INSERT INTO tbl1 values(1,50); 
INSERT INTO tbl1 values(1,20); 

INSERT INTO tbl1 values(2,10); 
INSERT INTO tbl1 values(2,20); 

INSERT INTO tbl1 values(3,22); 
INSERT INTO tbl1 values(3,89); 
INSERT INTO tbl1 values(3,500); 

問合せ:次のクエリは私に、各行の行番号を示します。

SELECT p_id,p_price,row_number() over(partition by p_id order by p_id) rn 
from tbl1 

各製品ID(p_id)の最初と最後に挿入されたレコードのみを取得したいと考えています。だから、内部で使用すると、最後の行を取得するには、パーティションで行番号を取得する選択1つのレベルアップ

SELECT p_id, p_price, rn from (
    SELECT *, last_value(rn) over(partition by p_id) as last from (
    SELECT p_id,p_price,row_number() over(partition by p_id order by p_id) rn 
    FROM tbl1 
) s1 
) s2 where rn=1 or rn=last; 

:あなたはこの使用して副問合せを行うことができます

p_id p_price  
----------------- 
1 100 
1 20 
2 10 
2 20 
3 22 
3 500 
+2

Postgresや大部分のSQLに「最初」と「最後」のレコードが挿入されていません。ここで何らかの順序を定義する必要があります。 –

+2

「最初の」または「最後の」挿入行はありません。そして、あなたが使用している 'order by 'は、あなたがソートするすべての値が同じであるので、あなたが望むものを与えません。したがって、データベースは自由に任意の順序でそれらの行を返します。 –

+0

' createdDate'レコードが挿入された日時を記録します。 – Viki888

答えて

1

期待される結果に数字(最初は常に1)。 トップレベルでフィルタを実行できます。

+0

これは最初と最後に挿入されたものではありません。結果は同じ 'p_id'のために時間の経過とともに変化します。 –

+0

@VaoTsunはい、そうです。挿入順序や日付を保存しないと、最初と最後に挿入された行が正しく渡されません。必要な場合は、テーブルを拡張し、クエリを変更してその処理を行うことができます。最終的に、この例ではIDはPKではありません。 PKは、例えば、挿入時間。 – quantummind

関連する問題