2017-07-19 2 views
0

J'ai une table avec trois colonnes, nom d'hôte, adresse et virtuelle. La colonne d'adresse est unique, mais un hôte peut avoir jusqu'à deux entrées d'adresse, une virtuelle et une non virtuelle. En d'autres termes, le nom d'hôte et la paire de colonnes virtuelles sont également uniques. Je veux produire un ensemble de résultats qui contient une entrée d'adresse pour un hôte donnant la priorité à l'adresse virtuelle. Par exemple, j'ai:Renvoie la première entrée dans la table pour chaque ligne étant donné un ordre de tri de colonne spécifique

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 

La requête doit retourner les résultats:

hostname | address 
---------+-------- 
first | 1.1.1.1 
second | 1.1.2.1 
third | 1.1.3.1 
fourth | 1.1.4.1 

Quelle est l'adresse virtuelle pour chaque hôte et l'adresse non-virtuelle pour les hôtes sans adresse virtuelle. Le plus proche que je suis venu est demandé pour un hôte spécifique:

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

Ce qui donne ceci:

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

Je voudrais obtenir ce pour chaque hôte dans le tableau avec une seule requête, si possible.

Répondre

2

Qu'est-ce que vous cherchez est une fonction RANK. Cela ressemblerait à ceci:

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

Ceci est une solution portable qui fonctionne également dans Oracle et SQL Server.

+0

'row_number()' obtiendrait la même chose ici, un peu moins cher. Mais 'DISTINCT ON' sera nettement plus rapide pour le cas d'utilisation (seulement 1 ou 2 lignes par' hostname'). –

2

Dans Postgres, le plus simple est distinct on:

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