2017-09-10 1 views
0

Dire que j'ai ces tables:SQL: Comment puis-je prendre seulement la première correspondance pour chacun dans une jointure interne?

UTILISATEUR

userId | Code Partenaire

PARTNER

PARTNERID | readableName | ... | partnerCode | ...

Et nous voulons:

select USER.userId, PARTNER.readableName 
from USER 
inner join PARTNER 
on PARTNER.partnerCode = USER.partnerCode 
where USER.userId = <someUser>; 

Cependant, pour chaque userId: paire dans USER Code Partenaire, il peut y avoir plusieurs entrées partenaires qui ont cette Code Partenaire. Nous nous soucions seulement de prendre le premier PARTNER.readableName que nous trouvons dans la table joinée (et l'ordre n'a pas d'importance).

Comment puis-je interroger ainsi? Merci beaucoup!

+0

Avez-vous une colonne userCode dans la table USER? –

+2

Étiquetez votre question avec la base de données que vous utilisez. –

+0

Oups! Oui, cela devrait lire USER.partnerCode :) – user3594939

Répondre

0

Dans la plupart des bases de données, vous pouvez le faire en utilisant la fonction de fenêtre standard ANSI row_number():

select u.userId, p.readableName 
from USER u inner join 
    (select p.*, 
      row_number() over (partition by p.partnerCode order by p.partnerCode) as seqnum 
     from PARTNER p 
    ) p 
    on p.partnerCode = u.userCode and seqnum = 1 
where u.userId = <someUser>; 

Compte tenu de la structure de votre requête, il serait souvent plus rapide d'utiliser une sous-requête corrélative:

select u.userId, 
     (select p.readableName 
     from PARTNER p 
     where p.partnerCode = u.userCode 
     fetch first 1 row only -- order doesn't matter, so there is no order by 
    ) as readableName 
from USER u 
where u.userId = <someUser>; 

Pour des performances optimales, vous voulez des index sur user(userId) et partner(partnerCode, readableName).

+0

Je suis intéressé de savoir pourquoi vous suggérez la fonction de fenêtre standard row_number() et non la fonction de fenêtre standard first_value()? first_values ​​semble avoir plus de sens pour moi dans ce cas. – Hogan

+0

@Hogan. . . 'row_number()' vient en premier à l'esprit. J'ai un bloc mental partiel contre 'first_value()', simplement parce que ce n'est pas aussi une fonction d'agrégation. –

+0

Vous savez ce que je vais dire ... row_number() n'est pas non plus une fonction d'agrégation. : D – Hogan