2010-03-03 15 views
46

Sto utilizzando il database Oracle. Voglio eseguire una query per controllare i dati tra due date.Data Oracle "Between" Query

NAME    START_DATE  
------------- ------------- 
Small Widget  15-JAN-10 04.25.32.000000 PM  
Product 1   17-JAN-10 04.31.32.000000 PM 



select * from <TABLENAME> where start_date 
BETWEEN '15-JAN-10' AND '17-JAN-10' 

Ma non ottengo alcun risultato dalla query precedente. Penso di dover usare "mi piace" e "%". Ma non so dove usarli. Per favore, getta delle luci su questo.

grazie in anticipo.

risposta

74

A giudicare dalla tua uscita sembra che hai definito START_DATE come timestamp. Se fosse una data normale, Oracle sarebbe in grado di gestire la conversione implicita. Ma dato che non è necessario gettare esplicitamente quelle stringhe per essere date.

SQL> alter session set nls_date_format = 'dd-mon-yyyy hh24:mi:ss' 
    2/

Session altered. 

SQL> 
SQL> select * from t23 
    2 where start_date between '15-JAN-10' and '17-JAN-10' 
    3/

no rows selected 

SQL> select * from t23 
    2 where start_date between to_date('15-JAN-10') and to_date('17-JAN-10') 
    3/

WIDGET       START_DATE 
------------------------------ ---------------------- 
Small Widget     15-JAN-10 04.25.32.000  

SQL> 

Ma abbiamo ancora solo una riga. Questo perché START_DATE ha un elemento temporale. Se non si specifica il componente orario, Oracle lo imposta automaticamente a mezzanotte. Questo va bene per il da lato della BETWEEN, ma non per il lato fino:

SQL> select * from t23 
    2 where start_date between to_date('15-JAN-10') 
    3      and to_date('17-JAN-10 23:59:59') 
    4/

WIDGET       START_DATE 
------------------------------ ---------------------- 
Small Widget     15-JAN-10 04.25.32.000 
Product 1      17-JAN-10 04.31.32.000 

SQL> 

modificare

Se non è possibile passare nel componente tempo ci sono un paio di scelte. Uno è quello di modificare la clausola WHERE per rimuovere l'elemento tempo dal criteri:

where trunc(start_date) between to_date('15-JAN-10') 
          and to_date('17-JAN-10') 

ciò potrebbe avere un impatto sulle prestazioni, perché squalifica qualsiasi indice b-albero su START_DATE. Dovresti invece creare un indice basato sulla funzione.

In alternativa si potrebbe aggiungere l'elemento tempo per la data nel codice:

where start_date between to_date('15-JAN-10') 
        and to_date('17-JAN-10') + (86399/86400) 

causa di questi problemi molte persone preferiscono evitare l'uso di between controllando confini data così:

where start_date >= to_date('15-JAN-10') 
and start_date < to_date('18-JAN-10') 
+0

Non posso passare la data unica di ora. –

+0

wow funziona bene APC ... grazie mille per il tuo supporto –

+0

@APC ha funzionato come un fascino in ORACLE 11 G – Alex

20

è necessario convertire quelle specifiche date più sotto, invece di stringhe, provate questo:

SELECT * 
FROM <TABLENAME> 
WHERE start_date BETWEEN TO_DATE('2010-01-15','YYYY-MM-DD') AND TO_DATE('2010-01-17', 'YYYY-MM-DD'); 

cura a che fare con il formato come specificato:

SELECT * 
FROM <TABLENAME> 
WHERE start_date BETWEEN TO_DATE('15-JAN-10','DD-MON-YY') AND TO_DATE('17-JAN-10','DD-MON-YY'); 
+0

Grazie per la risposta rapida. Ma sto ottenendo il Da e il data dal file di azione in questo formato "17-JAN-10". Quindi, in questo modo: SELECT \t * FROM uson_assetaccess WHERE accessdate TRA TO_DATE ('17 -FEB-10 ',' dd-MMM-yy ') AND TO_DATE ('17 -FEB-10', 'dd-MMM- aa '); Ma ho ricevuto un errore: ORA-01821: formato data non riconosciuto –

+0

Devi solo usare diversi identificatori di formato, sostituire "MMM" con "MON", vedere la mia modifica. –

+0

Grazie ancora per la risposta immediata. Ma ho usato quella query ma ora l'errore di formattazione della data è sparito. ora non ho trovato nessun errore trovato dati anche i dati ci sono nella tabella. Penso che nella data del tavolo ci sia tempo ma stiamo inviando solo con la data. È per questo motivo? Si prega di chiarire –

3

Come giustamente sottolineato da APC, la colonna start_date sembra essere un TIMESTAMP ma potrebbe essere un TIMESTAMP CON TIMEZONE LOCALE o TIMESTAMP CON il tipo di dati TIMEZONE. Questi potrebbero influenzare qualsiasi query che stavi facendo sui dati se il tuo server di database si trovava in un fuso orario diverso da te. Tuttavia, manteniamo questo semplice e presupponiamo che tu ti trovi nello stesso fuso orario del tuo server. Innanzitutto, per darti la sicurezza, controlla che start_date sia un tipo di dati TIMESTAMP.

Utilizzare il comando DESCRIBE di SQLPlus (o l'equivalente nell'IDE) per verificare che questa colonna sia un tipo di dati TIMESTAMP.

esempio

DESCRIVERE MyTable

dovesse manifestare:

Name  Null? Type 
----------- ----- ------------ 
NAME    VARHAR2(20) 
START_DATE  TIMESTAMP 

Se viene segnalato come un tipo = TIMESTAMP allora si può interrogare i tuoi intervalli di date con il più semplice conversione della data TO_TIMESTAMP, quella che richiede nessuna discussione (o immagine).

Utilizziamo TO_TIMESTAMP per garantire che qualsiasi indice nella colonna START_DATE venga considerato dall'ottimizzatore. La risposta di APC ha inoltre rilevato che un indice basato su funzione potrebbe essere stato creato su questa colonna e che influenzerebbe il predicato SQL ma non possiamo commentare in questa query. Se vuoi sapere come scoprire quali indici sono stati applicati alla tabella, posta un'altra domanda e possiamo rispondere separatamente.

Quindi, presumere che vi sia un indice su data_iniziale, che è un tipo di dati TIMESTAMP e si desidera l'ottimizzatore di prendere in considerazione, il vostro SQL sarebbe:

select * from mytable where start_date between to_timestamp('15-JAN-10') AND to_timestamp('17-JAN-10')+.9999999 

+.999999999 è molto vicino ma isn' t abbastanza 1 quindi la conversione di 17-JAN-10 sarà il più vicino alla mezzanotte di quel giorno possibile, quindi la query restituisce entrambe le righe.

Il database vedrà l'TRA come da 15-GEN-10 00: 00: 00: 0000000 a 17-GEN-10 23: 59: 59: 99999 e sarà quindi comprendere tutte le date dal 15, 16 e 17 gennaio 2010 qualunque sia la componente temporale del timestamp.

Spero che questo aiuti.

Dazzer

1

Data dell'asta Tra Query

SELECT * 
    FROM emp 
    WHERE HIREDATE between to_date (to_char(sysdate, 'yyyy') ||'/09/01', 'yyyy/mm/dd') 
    AND to_date (to_char(sysdate, 'yyyy') + 1|| '/08/31', 'yyyy/mm/dd'); 
1

seguente query può anche essere utilizzato:

select * 
    from t23 
where trunc(start_date) between trunc(to_date('01/15/2010','mm/dd/yyyy')) and trunc(to_date('01/17/2010','mm/dd/yyyy')) 
+2

Se una tabella è grande e la colonna della data è indicizzata, devi evitare espressioni, usa 'start_date between to_date (' 15/01/2010 ',' mm/gg/aaaa ') e to_date ('01/17/2010', 'mm/gg/aaaa') + 1 'invece. – Dmitry