2017-07-19 22 views
0

我有一個三列,主機名,地址和虛擬表。地址列是唯一的,但主機最多可以有兩個地址條目,一個是虛擬的,另一個是非虛​​擬的。換句話說,主機名和虛擬列對也是唯一的。我想生成一個結果集,其中包含一個給虛擬地址優先的主機的地址條目。例如,我有:給定一個特定的列排序順序,返回表中每一行的第一個條目

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 

這是虛擬地址爲每個主機和非虛擬地址缺乏一個虛擬地址的主機。我來最接近的是要求一個特定的主機:

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

其中給出這樣的:

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

我想獲得這個在表中的每個主機與一個單一的查詢,如果可能的。

回答

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

在Postgres裏,最簡單的方法是distinct on

SELECT DISTINCT ON (hostname) hostname, address 
FROM system 
ORDER BY hostname, virtual DESC NULLS LAST 
相關問題