web-dev-qa-db-fra.com

Oracle SQL - max () avec des valeurs NULL

J'ai une table qui a une série d'événements basés sur le temps, chacun lié avec une date de début et de fin. Pour l'événement le plus récent (actuel), la date de fin est NULL. Im essayant de réduire les lignes en double et d'afficher uniquement la date de début la plus ancienne et la dernière date de fin. Avec la valeur NULL dans le champ de date, cette ligne est ignorée. Je peux simuler une valeur de date de fin avec NVL (), mais cela obligera la logique frontale à rechercher et à remplacer cette valeur.

Existe-t-il de toute façon une fonction max () pour trier NULL aussi haut?

CREATE TABLE CONG_MEMBER_TERM
(
  CONG_MEMBER_TERM_ID  NUMBER(10)               NOT NULL,
  CHAMBER_CD           VARCHAR2(30 BYTE)        NOT NULL,
  CONG_MEMBER_ID       NUMBER(10)               NOT NULL,
  STATE_CD             CHAR(2 BYTE)             NOT NULL,
  DISTRICT             NUMBER(10),
  START_DT             TIMESTAMP(6) WITH TIME ZONE,
  END_DT               TIMESTAMP(6) WITH TIME ZONE
)

Cette requête fonctionne, mais supprime la ligne où la date de fin est NULL.

select CONG_MEMBER_ID, 
       district, 
       min(start_dt), 
       max(end_dt)
  from CONG_MEMBER_TERM
 where CONG_MEMBER_ID = 1716
 group by CONG_MEMBER_ID, district;

Cette requête corrige cela, mais j'ai maintenant une valeur de date de fin "factice" (9/9/9999). Quelque chose que je préfère ne pas avoir à coder.

select CONG_MEMBER_ID, 
       district, 
       min(start_dt), 
       max(nvl(end_dt, to_date('9/9/9999', 'mm/dd/yyyy')))
  from CONG_MEMBER_TERM
 where CONG_MEMBER_ID = 1716
 group by CONG_MEMBER_ID, district;

Merci.

24
nibeck

max(end_dt) keep (dense_rank first order by end_dt desc nulls first)

mise à jour:

SQL Fiddle

Configuration du schéma Oracle 11g R2 :

CREATE TABLE t
    (val int, s date, e date)
;

INSERT ALL 
    INTO t (val, s, e)
         VALUES (1, sysdate-3, sysdate-2)
    INTO t (val, s, e)
         VALUES (1, sysdate-2, sysdate-1)
    INTO t (val, s, e)
         VALUES (1, sysdate-1, null)
    INTO t (val, s, e)
         VALUES (2, sysdate-1, sysdate-.5)
    INTO t (val, s, e)
         VALUES (2, sysdate-.5, sysdate-.25)
SELECT * FROM dual
;

Requête 1 :

select val, min(s), max(e) keep (dense_rank first order by e desc nulls first)
from t group by val

Résultats:

| VAL |                          MIN(S) | MAX(E)KEEP(DENSE_RANKFIRSTORDERBYEDESCNULLSFIRST) |
---------------------------------------------------------------------------------------------
|   1 | November, 13 2012 14:15:46+0000 |                                            (null) |
|   2 | November, 15 2012 14:15:46+0000 |                   November, 16 2012 08:15:46+0000 |
23
be here now