在给定特定列排序顺序的每一行中,返回表中的第一个条目

时间:2017-07-19 23:21:13

标签: sql postgresql postgresql-9.4

我有一个包含三列的表,主机名,地址和虚拟。地址列是唯一的,但主机最多可以有两个地址条目,一个是虚拟的,一个是非虚​​拟的。换句话说,主机名和虚拟列对也是唯一的。我想生成一个结果集,其中包含一个主机的一个地址条目,优先考虑虚拟地址。例如,我有:

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 个答案:

答案 0 :(得分:2)

在Postgres中,最简单的方法是distinct on

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

答案 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中运行的便携式解决方案。