web-dev-qa-db-fra.com

Comment sélectionner le top 1 et classé par date dans Oracle SQL?

Il y a une réponse claire comment sélectionner top 1 :

select * from table_name where rownum = 1

et comment commander par date en ordre décroissant:

select * from table_name order by trans_date desc

mais ils ne fonctionnent pas (rownum n'est pas généré conformément à trans_date):

... where rownum = 1 order by trans_date desc

La question est de savoir comment sélectionner le premier 1 également ordonné par date?

2
Ivan Gerasimenko
... where rownum = 1 order by trans_date desc

Ceci sélectionne un enregistrement choisi arbitrairement (where rownum = 1) puis trie cet enregistrement (order by trans_date desc).

Comme le montre Ivan, vous pouvez utiliser une sous-requête dans laquelle vous commandez les enregistrements, puis conservez le premier enregistrement avec where rownum = 1 dans la requête externe. Ceci, cependant, est extrêmement spécifique à Oracle et viole le standard SQL où un résultat de sous-requête est considéré comme non ordonné (c'est-à-dire que la clause order by peut être ignorée par le SGBD).

Alors mieux vaut utiliser la solution standard. À partir d'Oracle 12c:

select * 
from table_name 
order by trans_date desc
fetch first 1 row only;

Dans les anciennes versions:

select *
from
(
  select t.*, row_number() over (order by trans_date desc) as rn
  from table_name t
)
where rn = 1;
14
Thorsten Kettner

Vous pouvez utiliser les fonctions de fenêtre pour cela: 

select t.*
from (
  select *, 
         min(trans_date) over () as min_date,
         max(trans_date) over () as max_date
  from the_table 
) t 
where trans_date = min_date 
   or trans_date = max_date;

Une autre option serait de rejoindre la table dérivée 

select t1.*
from the_table 
  join ( 
    select min(trans_date) over () as min_date,
           max(trans_date) over () as max_date
    from the_table
) t2 on t1.trans_date = t2.min_date 
     or t1.trans_date = t2.max_date;

Vous ne savez pas lequel serait le plus rapide, vous devez vérifier le plan d'exécution

1

Les versions Oracle modernes ont FETCH FIRST:

select * from table_name order by trans_date desc
fetch first 1 row only
1
jarlh

Il devrait y avoir une sous-requête pour que la combinaison rownum & order puisse fonctionner:

select * from (select * from table_name order by trans_date desc) AS tb where rownum = 1
0
Ivan Gerasimenko