Dans Oracle 12.1 et plus, cela peut se faire facilement avec la clause match_recognize
, comme ceci:
select user_id, email_address
from inputs
match_recognize (
partition by user_id
order by preferred_email desc nulls last
all rows per match
pattern (^x)
define x as 0 = 0
)
;
Cependant, cette solution (comme ainsi que certains des autres proposés ici) présente une faiblesse potentielle: il repose sur l'ordre explicite de 'Y'
vs 'N'
, et il suppose que ce sont les seules valeurs possibles dans la colonne preferred_email
(et aussi que la colonne n'est pas nullable).
Il serait préférable, si la colonne preferred_email
n'est pas contraint de non annulable et seules valeurs possibles 'Y'
et 'N'
, d'avoir une clause d'ordre comme
order by case preferred_email when 'Y' then 0 end [...]
Malheureusement, la clause match_recognize
pouvez commander seulement par colonnes , pas par des expressions. (Dans l'espoir que cela sera traité dans le futur!) Dans ce cas, une solution globale utilisant la fonction d'agrégat FIRST/LAST, comme dans la réponse de MT0, est le meilleur choix - mais avec la clause ORDER BY modifiée en conséquence.
select user_id,
max(email_address) keep (dense_rank first
order by case preferred_email when 'Y' then 0 end) as email_address
from inputs
group by user_id
;
Alors, quelle est la sortie désirée? [email protected] pour les 3 user_ids? Ou [email protected] juste pour user_id # 25 et puis [email protected] et [email protected] pour # 26 et # 27 respectivement? –
Quelle version d'Oracle utilisez-vous? Différentes versions viennent avec des outils différents qui peuvent être utilisés pour les questions top-n (le plus grand-n-par-groupe). – mathguy