2017-09-08 2 views
2

tilteの説明が正確には私の望むものと異なる場合があります。ここに例があります。与えられたテーブルt1:PostgreSQL:同じ列を持つ行の中の最小の値を持つ行を選択してください。

src dest length path 
a e 5 a b e 
a d 2 a c d 
a g 6 a c g 
a e 3 a c e 
a e 4 a g e 
a d 2 a b d 

各(src、dest)ペアについて、エントリが1つしかない場合はそれを保持します。複数のエントリがある場合は、長さが同じである場合は最小長を選択し、長さが同じ場合はすべて保持します。 出力は次のようになります。

src dest length path 
a d  2 a c d 
a g  6 a c g 
a e  3 a c e 
a d  2 a b d 

私は、PostgreSQLを使用して、それに近づくことができる方法は?

+0

あなたがこれまでに試してみましたでしょうか? – mabe02

+0

https://stackoverflow.com/questions/tagged/postgresql+greatest-n-per-group –

答えて

0

私はあなたが二回スキャンテーブルなしでそれを作ることができると思ういけない:

t=# with g as (select src,dest,min(length) from t1 group by src,dest) 
select t1.* from t1 
join g on t1.src = g.src and t1.dest = g.dest and length = min 
; 
src | dest | length | path 
-----+------+--------+------ 
a | d |  2 | acd 
a | d |  2 | abd 
a | e |  3 | ace 
a | g |  6 | acg 
(4 rows) 
+0

ウィンドウ機能を使用する場合は、2回参加またはスキャンする必要はありません。 [Gordon Linoffの答え](https://stackoverflow.com/a/46113750/108326)を参照してください。 – markusk

+0

はい、 'dense_rank()'は良いアイデアです –

2

私はウィンドウ関数を使用します。

select t.* 
from (select t.*, 
      dense_rank() over (partition by src, dest order by length) as seqnum 
     from t 
    ) t 
where seqnum = 1; 
+0

'dense_rank'を' rank'より優先させる理由は?ランク1のみをチェックしているので、両方ともこのクエリで同じ結果が得られるはずです。 – markusk

+0

@markusk。 。 。何の理由もありません。私は通常 'rank()'を使っています。 –

+0

クエリが目的の出力と完全に一致しない場合は、追加の列としてランクも含まれます。一番外側のクエリを 'src、dest、length、(...)where seqnum = 1'から選択することで簡単に修正されました。 – markusk

関連する問題