Oracle
 sql >> Base de données >  >> RDS >> Oracle

Requête SQL Sélectionnez le premier rang 1 ligne à partir de plusieurs rangs/groupe

Vous pouvez spécifier de nombreuses conditions de classement dans votre fonction analytique

SELECT *
  FROM (SELECT id,
               col1,
               col2,
               col3,
               dense_rank() over (partition by id
                                      order by (case when col1 = 'xyz' 
                                                     then 1 
                                                     else 0 
                                                 end) desc,
                                               col2 asc,
                                               col3 asc) rnk
          FROM your_table)
 WHERE rnk = 1

Je suppose que vous voulez dense_rank étant donné que vous avez utilisé le dense_rank étiquette. Vous ne dites pas comment vous voulez gérer les liens ou si les liens sont même possibles, il n'est donc pas clair d'après la question elle-même si vous souhaitez utiliser le rank , dense_rank , ou row_number fonctions analytiques. Si vous ne récupérez que la ligne la mieux classée par id , rank et dense_rank se comportera de manière identique et renverra plusieurs lignes s'il y a des égalités pour la première place. row_number renverra toujours une seule ligne en brisant arbitrairement l'égalité. Si vous souhaitez récupérer des lignes autres que la première ligne par id , alors vous devrez penser aux égalités et vous obtiendrez un comportement différent de rank et dense_rank . Si deux lignes sont à égalité pour la première, dense_rank attribuera à la troisième ligne un rnk de 2 tandis que rank lui attribuera un rnk de 3.

Cela semble fonctionner pour les exemples de données que vous avez publiés

SQL> ed
Wrote file afiedt.buf

  1  with x as (
  2  select 1 id, 'abc' col1, to_date('01/01/2012', 'MM/DD/YYYY') col2, null col3 from dual union all
  3  select 1 id, 'abc' col1, to_date('01/01/2012', 'MM/DD/YYYY') col2, 'A' col3 from dual union all
  4  select 2 id, 'abc' col1, to_date('01/01/2012', 'MM/DD/YYYY') col2, null col3 from dual union all
  5  select 2 id, 'abc' col1, to_date('01/02/2012', 'MM/DD/YYYY') col2, null col3 from dual union all
  6  select 3 id, 'abc' col1, to_date('01/02/2012', 'MM/DD/YYYY') col2, null col3 from dual union all
  7  select 3 id, 'xyz' col1, to_date('01/01/2012', 'MM/DD/YYYY') col2, null col3 from dual union all
  8  select 4 id, 'abc' col1, to_date('01/02/2012', 'MM/DD/YYYY') col2, null col3 from dual union all
  9  select 4 id, 'xyz' col1, to_date('01/01/2012', 'MM/DD/YYYY') col2, null col3 from dual union all
 10  select 4 id, 'xyz' col1, to_date('01/02/2012', 'MM/DD/YYYY') col2, null col3 from dual
 11  )
 12  SELECT *
 13    FROM (SELECT id,
 14                 col1,
 15                 col2,
 16                 col3,
 17                 dense_rank() over (partition by id
 18                                        order by (case when col1 = 'xyz'
 19                                                       then 1
 20                                                       else 0
 21                                                   end) desc,
 22                                                 col2 asc,
 23                                                 col3 asc) rnk
 24            FROM x)
 25*  WHERE rnk = 1
SQL> /

        ID COL COL2      C        RNK
---------- --- --------- - ----------
         1 abc 01-JAN-12 A          1
         2 abc 01-JAN-12            1
         3 xyz 01-JAN-12            1
         4 xyz 01-JAN-12            1