2017-07-19 75 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 
相关问题