2012-11-16 15 views
20

Ho una tabella che contiene una serie di eventi basati sul tempo, ciascuno associato a una data di inizio e di fine. Per l'evento più recente (corrente), la data di fine è NULL. Sto cercando di comprimere le righe duplicate e mostrare solo la prima data di inizio e l'ultima data di fine. Con il NULL nel campo della data, quella riga viene ignorata. Posso inventare un valore di data di fine con NVL(), ma ciò farà sì che la logica front-end cerchi e sostituisca quel valore.Oracle SQL - max() con valori NULL

Esiste comunque la funzione max() per ordinare NULL in alto?

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 
) 

Questa query funziona, ma elimina la riga in cui la data di fine è 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; 

Questa query correzioni, ma ora ho un "fittizio" Valore data di fine (9/9/9999). Qualcosa che preferirei non dover codificare.

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; 

Grazie.

+2

Hai un sacco di domande in cui non hai accettato una risposta, si otterrà più interesse per le vostre domande se si può tornare indietro e segnare le risposte corrette (usando il segno di spunta a sinistra della risposta). – bendataclear

+1

Non ero nemmeno a conoscenza della funzione Accetta. Tornerà e aggiornerà alcune delle risposte più vecchie. – nibeck

risposta

20

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

UPD:

SQL Fiddle

Oracle 11g R2 Setup Schema:

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 
; 

Query 1:

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

Results:

| 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 | 
+0

Hmmmm, rango elevato. Non su queste funzioni analitiche. Gli darò un vortice e vedrò se riesco a farlo funzionare. Sembra promettente. – nibeck

+2

Questo funziona meravigliosamente! Grazie. – nibeck

+0

Ho bisogno di questa sintassi simile per MS SQL Server ... c'è qualche idea? –