2010-08-10 3 views
1

Je cours des demandes sur une base de données Oracle. L'une de mes tables contient des tranches de temps pour les éléments et il peut y avoir plusieurs créneaux horaires pour le même élément pour que l'exemple suivant est correct:Comment retourner maxvalue ou nullvalue dans SQL?

ID ELEMENT_ID BEGIN_DATE END_DATE 
-------------------------------------------- 
1  1    01/01/2007 01/06/2007 
2  1    01/06/2007 

3  2    01/01/2006 01/07/2006 
4  2    01/07/2006 31/12/2006 

Le créneau horaire pour lequel END_DATE n'est pas rempli signifie qu'il est encore en cours d'exécution (donc, c'est l'intervalle de temps le plus récent pour l'élément).

Ainsi, lorsque je recherche le plus récent END_DATE pour chaque élément, je veux obtenir les lignes # 2 et # 4. Donc, le problème que je suis confronté est de considérer NULL comme le plus haut END_DATE ...

Est-il possible de le faire en une seule requête SQL?

Bien sûr, j'essayé un simple:

SELECT MAX(END_DATE) FROM ...

mais ce n'est pas enought à cause des valeurs NULL.

Merci d'avance.

Répondre

6

Modifiez les valeurs NULL à une valeur future

SELECT MAX(NVL(END_DATE,SYSDATE + 1) ... 
+0

Cela suppose que rien de votre end_dates sont dans le futur, ce qui semble être le cas selon votre exemple. – LesterDove

+0

C'est le cas, aucune de mes dates de fin n'est à venir. Merci pour l'extrait, ça marche bien !! Cependant, j'ai encore un petit problème parce que ma prochaine étape est de sélectionner la ligne entière pour le MAX identifié (END_DATE) ... donc l'insertion d'une fausse date dans END_DATE n'est plus compatible avec quelque chose comme ' SELECT * FROM MyTable WHERE END_DATE = (SELECT MAX (...)); 'Un dernier conseil pour moi? :) – Clem

+0

Techniquement, votre approche fonctionnerait, tant que vous comparez les pommes aux pommes et remplacez les valeurs nulles des deux côtés de la comparaison: SELECT * FROM MyTable O WH NVL (END_DATE, SYSDATE + 1) = (SELECT MAX (. ..)); Il existe probablement un certain nombre d'autres façons ... – LesterDove

3

Essayez:

select element_id, max(coalesce(end_date, date '4000-12-31')) as max_end_date 
from ... 
3

Utilisez une clause ORDER BY avec NULLS FIRST, par exemple:

SELECT DISTINCT 
     FIRST_VALUE(id) 
     OVER (PARTITION BY element_id 
      ORDER BY end_date DESC NULLS FIRST) latest_id, 
     element_id, 
     FIRST_VALUE(begin_date) 
     OVER (PARTITION BY element_id 
      ORDER BY end_date DESC NULLS FIRST) latest_id, 
     FIRST_VALUE(end_date) 
     OVER (PARTITION BY element_id 
      ORDER BY end_date DESC NULLS FIRST) latest_id 
FROM ... 


ID ELEMENT_ID BEGIN_DATE END_DATE 
-------------------------------------------- 
2  1    01/06/2007 
4  2    01/07/2006 31/12/2006 
+0

Excellente solution aussi! J'ai codé le précédent mais gardez votre méthode à l'esprit pour la prochaine fois! Merci. – Clem

Questions connexes