2017-07-19 1 views
0

私は3つの列、ホスト名、アドレス、および仮想を持つテーブルを持っています。アドレス列は一意ですが、ホストは仮想エントリと仮想エントリ以外の2つのアドレスエントリを持つことができます。つまり、ホスト名と仮想列のペアも一意です。私は、仮想アドレスに優先順位を与えるホストのアドレスエントリを1つ含む結果セットを生成したい。例えば、私が持っている:特定の列のソート順が指定されたすべての行について、テーブルの最初のエントリを返します。

hostname | address | virtual 
---------+---------+-------- 
first | 1.1.1.1 | TRUE 
first | 1.1.1.2 | FALSE 
second | 1.1.2.1 | FALSE 
third | 1.1.3.1 | TRUE 
fourth | 1.1.4.2 | FALSE 
fourth | 1.1.4.1 | TRUE 

クエリが結果を返す必要があります。

すべてのホストのための仮想アドレス、および仮想アドレスを欠いているホストのための非仮想アドレスである
hostname | address 
---------+-------- 
first | 1.1.1.1 
second | 1.1.2.1 
third | 1.1.3.1 
fourth | 1.1.4.1 

。私が来て最も近い1つの特定のホストを求めて:

SELECT hostname, address 
FROM system 
WHERE hostname = 'first' 
ORDER BY virtual DESC NULLS LAST 
LIMIT 1; 

これを与える:

hostname | address 
---------+-------- 
first | 1.1.1.1 

私は単一のクエリ可能な場合と、テーブル内のすべてのホストのためにこれを取得したいと思います。 Postgresの、最も簡単な方法で

答えて

2

RANK機能です。

SELECT * FROM (
    SELECT hostname, address 
    , RANK() OVER (PARTITION BY hostname ORDER BY virtual DESC NULLS LAST) AS rk 
    FROM system 
) 
WHERE rk = 1 

これは、OracleおよびSQL Serverでも動作するポータブルなソリューションです。

+0

'row_number()'はここで同じように少し安くなります。しかし、DISTINCT ONは、ユースケース(hostnameにつき1行または2行)でかなり高速になります。 –

2

distinct onです:あなたが探しているもの

SELECT DISTINCT ON (hostname) hostname, address 
FROM system 
ORDER BY hostname, virtual DESC NULLS LAST 
関連する問題