web-dev-qa-db-fra.com

Date Oracle "Entre" Requête

J'utilise la base de données Oracle. Je veux exécuter une requête pour vérifier les données entre deux dates.

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'

Mais je ne reçois aucun résultat de la requête ci-dessus. Je pense que je dois utiliser "like" et "%". Mais je ne sais pas où les utiliser. S'il vous plaît jeter quelques lumières sur cela.

merci d'avance.

51
Gnaniyar Zubair

À en juger par votre sortie, il semble que vous ayez défini START_DATE comme un horodatage. S'il s'agissait d'une date normale, Oracle serait en mesure de gérer la conversion implicite. Mais comme ce n'est pas le cas, vous devez explicitement transtyper ces chaînes pour qu'elles soient des dates.

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> 

Mais nous n'avons toujours qu'une rangée. En effet, START_DATE a un élément time. Si nous ne spécifions pas le composant heure, Oracle le configurera par défaut à minuit. C’est parfait pour le côté de du BETWEEN mais pas pour le jusqu’au côté:

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>

edit

Si vous ne pouvez pas passer à la composante temps, vous avez le choix. L'une consiste à modifier la clause WHERE pour supprimer l'élément time des critères:

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

Cela peut avoir un impact sur les performances, car il disqualifie tout index b-tree sur START_DATE. Vous auriez plutôt besoin de créer un index basé sur une fonction.

Vous pouvez également ajouter l'élément time à la date dans votre code:

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

A cause de ces problèmes, beaucoup de gens préfèrent éviter l'utilisation de between en vérifiant les limites de date comme ceci:

where start_date >= to_date('15-JAN-10') 
and start_date < to_date('18-JAN-10')
82
APC

Vous devez convertir ceux-ci en dates réelles au lieu de chaînes, essayez ceci:

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

Édité pour traiter le format comme spécifié:

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

Comme APC l'a fait remarquer à juste titre, votre colonne start_date semble être un horodatage, mais il pourrait également s'agir d'un horodatage avec fuseau horaire local ou d'un type d'horodatage avec horodatage. Celles-ci pourraient bien influencer vos requêtes sur les données si votre serveur de base de données était dans un fuseau horaire différent de vous. Cependant, gardons cela simple et supposons que vous êtes dans le même fuseau horaire que votre serveur. Tout d'abord, pour vous donner la confiance, vérifiez que la date_début est un type de données TIMESTAMP.

Utilisez la commande SQLPlus DESCRIBE (ou l’équivalent dans votre IDE) pour vérifier que cette colonne est un type de données TIMESTAMP.

par exemple

DÉCRIRE mytable

Devrait signaler:

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

S'il est signalé sous la forme Type = TIMESTAMP, vous pouvez alors interroger vos plages de dates avec la conversion de date TO_TIMESTAMP la plus simple, une conversion qui ne nécessite aucun argument (ni aucune image).

Nous utilisons TO_TIMESTAMP pour nous assurer que tout index de la colonne START_DATE est pris en compte par l'optimiseur. La réponse d'APC a également noté qu'un index basé sur une fonction aurait pu être créé sur cette colonne et qui aurait une influence sur le prédicat SQL, mais nous ne pouvons pas en parler dans cette requête. Si vous voulez savoir comment trouver les index qui ont été appliqués à la table, posez une autre question à laquelle nous pourrons répondre séparément.

Donc, en supposant qu'il existe un index sur start_date, qui est un type de données TIMESTAMP et que vous souhaitez que l'optimiseur le tienne compte, votre code SQL serait:

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

+999999999 est très proche de 1, mais n'est pas tout à fait à 1; la conversion du 17-JAN-10 sera donc aussi proche de minuit que possible. Par conséquent, votre requête renvoie les deux lignes.

La base de données verra le ENTRE ENTRE du 15-JAN-10 00: 00: 00: 0000000 à 17- JAN-10 23: 59: 59: 99999 et inclura donc toutes les dates des 15, 16 et 17 janvier 2010, quelle que soit la composante heure de l'horodatage.

J'espère que ça t'as aidé.

Dazzer

3
Darren Atkinson

Date entre la requête

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
user3496353

La requête suivante peut également être utilisée:

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'))
1
Ajay