[oracle] Requete avec filtre sur une date

Requete avec filtre sur une date [oracle] - SQL/NoSQL - Programmation

Marsh Posté le 10-02-2010 à 11:01:24    

Bonjour,
 
Je souhaites effectuer une requete avec comme filtre la date de la veille.
 
Voici un exemple :

Code :
  1. select dateent AS R1, numimeient AS R2
  2. from fiches
  3. where dateent >= SYSDATE - 1
  4. and dateent < SYSDATE
  5. order by dateent desc


 
Cette requete me renvoie les resultats pour la veille mais egalement pour la date du jour (le 09 et le 10 pour aujourd'hui).
 
J'ai essaye "where dateent = SYSDATE - 1", et la je n'ai aucun resultat.
 
Auriez vous une solution ?

Reply

Marsh Posté le 10-02-2010 à 11:01:24   

Reply

Marsh Posté le 10-02-2010 à 11:08:31    

c'est parce que SYSDATE te renvoie la date jusqu'à une précision à la seconde, tu coup "SYSDATE-1" te retournera la veille à la seconde près (par exemple 09/02/2010 11:10:53)
 
le plus simple c'est de faire un truc du style

Code :
  1. ... WHERE trunc(dateent)=trunc(sysdate-1)


c'est un peu à l'arrache mais ca marche bien

Reply

Marsh Posté le 10-02-2010 à 11:26:25    

Je n'y avait pas pense, merci beaucoup ca fonctionne tres bien.

Reply

Marsh Posté le 11-02-2010 à 09:28:08    

En fait j'ai un petit soucis avec cette fonction, elle augmente enormement le temps d'execution de la requete (la table contient des millions d'enregistrements).  
 
J'ai essaye ca :
DateENT >= CURRENT_DATE-1 AND DATEENT < CURRENT_DATE
 
Le temps d'execution est tres rapide mais je n'obtiens pas le meme resultat ; et je ne sais pas quel resultat est bon !
 
Auriez vous une solution ?

Reply

Marsh Posté le 11-02-2010 à 10:01:12    

c'est pour ca que j'ai dis que c'était à l'arrache...
le temps d'exécution est dû à le fait qu'oracle soit obligé d'appliquer la fonction trunc() à toutes les entrées
 
tu peux créer un index calculé

Code :
  1. CREATE INDEX pouet ON fiches(trunc(dateent);


 
ou revoir la requête

Reply

Marsh Posté le 11-02-2010 à 10:40:46    

Merci pour ton aide couak, malheureusement je n'ai pas les droits necessaires pour creer un index. N'existe t il pas un moyen de comparer 2 dates sans prendre en compte l'heure ?  
 
Mon champ DateEnt contient la date et l'heure, si j'utilise la fonction CURRENT_DATE (DateENT = CURRENT_DATE), est ce que mon resultat va prendre par exemple pour aujourd'hui tous les enregistrements du 11/02/10 de 00:00:00 a 23:59:59 ?


Message édité par shooker le 11-02-2010 à 10:42:59
Reply

Marsh Posté le 11-02-2010 à 11:25:28    

utilise un mélange de BETWEEN et de TRUNC()

Reply

Marsh Posté le 11-02-2010 à 11:35:21    

utilise effectivement le truc de couak, et pour être complet faire un between entre trunc() et trunc+0.99999

Reply

Marsh Posté le 11-02-2010 à 14:05:07    

Le probleme est que la fonction trunc() utilise trop de ressources, l'execution de la requete devient tres lente. C'est pour cette raison que je n'ai pas envie de l'utiliser sur des tables comprenant des millions d'enregistrements. N'y a t il pas une autre alternative ?

Reply

Marsh Posté le 11-02-2010 à 15:43:47    

le trunc ne prendra quasi rien, a mon avis tu confonds
 

Code :
  1. trunc(ma_date1) BETWEEN trunc(sysdate) trunc(sysdate)+0.99999


 
et  
 

Code :
  1. ma_date1 BETWEEN trunc(sysdate) trunc(sysdate)+0.99999


 
les deux seront traités de manière très différente pour peu que tu ais un index sur ma_date1, a savoir qu'il va l'utiliser dans le 2ème cas et pas dans le premier.
Le trunc suivant le between compte pour du beurre et est insignifiant en temps machine.


Message édité par casimimir le 11-02-2010 à 15:44:18
Reply

Marsh Posté le 11-02-2010 à 15:43:47   

Reply

Marsh Posté le 11-02-2010 à 16:59:36    

Je vois ce que tu veux dire, le trunc avant le between sera execute sur chacun des enregistrements. J'ai essaye ta 2eme solution, mais le temps de reponse est toujours aussi long. Pour info il n'y a pas d'index sur ma colonne DateEnt.
 
Il faudrait que la requete ne prenne pas en compte l'heure inclue dans DateEnt, seulement prendre en compte la date, ce serait parfait.

Reply

Marsh Posté le 11-02-2010 à 17:37:56    

penche toi sur le plan d'exécution, je suis sûr qu'il faut un FTS et qu'il va te falloir un index

Reply

Marsh Posté le 12-02-2010 à 11:30:39    

L'index me parait inevitable effectivement, par contre je ne connais pas le FTS, peux tu m'en dire plus ?

Reply

Marsh Posté le 12-02-2010 à 13:57:10    

full table scan : un balayage complet de la table pour trouver des données
 
un index permet "en général" de limiter les FTS qui sont consommateurs d'I/O, de tte facon il faudra bien qu'un DBA s'y penche car tu as beaucoup de leviers d'action pour avoir un bon plan d'exécution : index, statistique, etc.

Reply

Marsh Posté le 12-02-2010 à 14:25:56    

D'accord, merci pour toutes ces explications.
 
Je vais essayer de m'arranger pour resoudre tout ca avec l'informaticien charge de la base de donnees, qui est toujours trop occupe...

Reply

Marsh Posté le 27-03-2013 à 10:09:44    

Salut, je déterre le sujet.
Pourquoi ne pas essayer de transformer la date comme ceci :
 

Code :
  1. to_date(to_char(sysdate-1,'YYYY/MM/DD') || ' 00:00:00','YYYY/MM/DD HH24:MI:SS')


 
Tu fais la même chose avec les deux dates à comparer et tu retrouve avec des date initialisées avec des heures:minutes:secondes à 00:00:00

Reply

Marsh Posté le 27-03-2013 à 21:39:14    

3 ans après ?  [:netbe]

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed