IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Développement SQL Server Discussion :

Comparaison date et datetime


Sujet :

Développement SQL Server

  1. #1
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 239
    Points
    4 239
    Par défaut Comparaison date et datetime
    Bonjour,

    Je suis persuadé que cela doit être trivial mais je sèche...

    Dans un select statement, je veux effectuer un filtre sur une date.

    Je fais donc quelque chose comme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    select *
    from maTable
    where maColonneDateTime = '2012-01-05'
    Le souci, c'est que cela ne me retournera jamais de résultat car, comme on peut le voir dans l'estimated execution plan, la comparaison que sql server effectue est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    maColonneDateTime = '2012-01-05 00:00:00.000'
    Or il y a bien une donnée temporelle également dans mes colonnes.

    Je pourrais contourner le problème en utilisant l'une ou l'autre fonction de traitement des chaines de caractère pour extraire la partie date de ma colonne pour effectuer la comparaison mais j'imagine que quelque chose d'aussi basique est prévu quelque part...
    Non ?

    Bref, vous faites comment vous ?

    Griftou.

    P.S. : Oui c'est la première fois que je travaille avec des colonnes datetime (c'était du char(8) avant)
    Kropernic

  2. #2
    Expert éminent sénior
    Avatar de mikedavem
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2005
    Messages
    5 450
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Distribution

    Informations forums :
    Inscription : Août 2005
    Messages : 5 450
    Points : 12 891
    Points
    12 891
    Par défaut
    Bonjour,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT *
    FROM maTable
    WHERE maColonneDateTime BETWEEN '2012-01-05' AND '2012-01-05 23:59:59'
    ou encore

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT *
    FROM maTable
    WHERE maColonneDateTime >= '2012-01-05' 
     AND maColonneDateTime < '2012-01-06' -- Ca ferait plaisir à Elsuket :-)
    ou encore depuis SQL Server 2008

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT *
    FROM maTable
    WHERE CAST(maColonneDateTime AS DATE) = '2012-01-05';
    ++

  3. #3
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Il suffit d'utiliser des comparaisons au lieu d'une égalité.
    Avis personnel, je préfère convertir mes constantes en date :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT *
      FROM maTable
     WHERE maColonneDateTime >= convert(datetime, '2012-01-05', 121)
       AND maColonneDateTime <  convert(datetime, '2012-01-06', 121)

  4. #4
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 239
    Points
    4 239
    Par défaut
    Ok donc au final, il faut toujours travailler sur des intervalles de dates.

    Je suis loin d'être un expert dans ce domaine mais n'est-ce pas bizarre de devoir faire ce genre de chose ?

    Si je caricature, c'est un peu comme si pour faire
    je devais faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    where id >= 3 and id < 4
    Perso, ça me choque...

    Il y a une raison technique ou logique derrière cette contrainte d'intervalle sur les dates ?

    Griftou.
    Kropernic

  5. #5
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Oui, ce sont les heures / minutes / secondes qui sont portées par le type datetime.

    Pour reprendre votre analogie, dans votre colonne vous n'avez pas 3 mais 3,5.

  6. #6
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 239
    Points
    4 239
    Par défaut
    Tout à fait d'accord avec vous mais pour l'exemple, il existe la fonction floor qui me permet d'extraire facilement la partie qui m'intéresse.

    Je suis étonné qu'il n'existe pas de fonction permettant d'extraire facilement la partie date d'une donnée datetime. J'ai regardé du côté de la fonction datepart mais même là, cela ne semble pas être le cas (du moins pas directement).
    Kropernic

  7. #7
    Expert éminent sénior
    Avatar de mikedavem
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2005
    Messages
    5 450
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Distribution

    Informations forums :
    Inscription : Août 2005
    Messages : 5 450
    Points : 12 891
    Points
    12 891
    Par défaut
    Avant SQL Server 2008 vous aviez le type datetime qui stocke la date ET l'heure. Le stockage est composé de 2 entiers pour la partie DATE et la partie HEURE.

    Avec un FLOOR vous allez extraire la partie DATE mais vu que vous reconvertissez par la suite en DATETIME, vous aurez toujours une notion d'heure.

    Pour pallier ce problème de conversion et d'extraction de la partie heure, les types DATE et TIME a été implémenté avec 2008. Vous pouvez maintenant vous concentrer sur la partie que vous intéresse réellement.

    ++

  8. #8
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 239
    Points
    4 239
    Par défaut
    Je crois que si je dis à mon chef qu'il faut passer à sql server 2008 pcq les dates c'est chiant sous 2005, il va quand même un peu tirer la gueule ^^.

    Bon et bien au moins maintenant, je sais.

    Merci pour vos explications !

    Griftou.
    Kropernic

  9. #9
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Si vous appliquez une fonction sur votre colonne, vous perdez l'éventuel apport d'un index ou d'une partition.

    C'est toujours moins coûteux de travailler sur des constantes que sur les colonnes de votre table, d'où l'utilisation des comparaisons plutôt que la reconversion de votre colonne.

    Si vous voulez vous faciliter l'écriture de requête, vous pouvez créer une colonne calculée pour extraire la partie DATE de votre DATETIME et l'indexer.

  10. #10
    Expert éminent sénior
    Avatar de mikedavem
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2005
    Messages
    5 450
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Distribution

    Informations forums :
    Inscription : Août 2005
    Messages : 5 450
    Points : 12 891
    Points
    12 891
    Par défaut
    Il n'y a pas de raison de passer à SQL Server pour une telle raison :-)

    Il suffit de borner vos dates dans vos prédicats comme expliqué plus haut dans le thread.

    ++

  11. #11
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 239
    Points
    4 239
    Par défaut
    Bah maintenant que je le sais, je vais travailler avec des intervalles et l'opérateur between. Ce n'est pas bien sorcier.

    Par curiosité, j'ai quand même effectuer deux select de test. L'un avec des conversions et l'autre avec between.

    1° Les conversions sont quand même plus ennuyeuses à écrire que between et 2 dates.
    2° Le coût de la requête avec conversion et dramatiquement supérieur à celle de l'opérateur between (comme vous le mentionnez).

    Bref, j'aurai encore appris un truc ^^.


    Tant que j'y suis, une petite question annexe. Je fais cette requête sur une vue. Les filtres placés dans la clause where font-ils appel aux index de la table de base ou bien faut-il que je recrée les index pour cette vue ?
    N.B. : Il s'agit d'une table de transactions caisse et j'ai crée une vue par année.
    Kropernic

  12. #12
    Modérateur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2005
    Messages
    5 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2005
    Messages : 5 826
    Points : 12 371
    Points
    12 371
    Par défaut
    Bonjour,

    Tant que j'y suis, une petite question annexe. Je fais cette requête sur une vue. Les filtres placés dans la clause where font-ils appel aux index de la table de base ou bien faut-il que je recrée les index pour cette vue ?
    Lorsque vous spécifiez une vue, SQL Server résout les tables qui participent à la spécification de la vue, et e sert des index qui peuvent servir la requête s'il y a en a.

    Si vous voulez voir ce que SQL Server prévoit qu'il va faire, il vous suffit de regarder le plan d'exécution estimé : écrivez la requête spécifiant le vue, surlignez-là, puis appuyez sur CTRL+L : le plan d'exécution s'affiche, et vous indique les tables et les index utilisés.
    Si vous voulez voir le plan d'exécution réel, appuyez sur CTRL+M avant d'exécuter la requête, puis exécutez-la : à la fin de celle-ci, un nouvel onglet s'affichera et vous donnera le plan d'exécution réel.

    L'indexation d'une vue est une méthode d'optimisation qui a de nombreuses restrictions et qui s'applique à des cas très particuliers.
    Il faut garder à l'esprit que la maintenance des index sur une vue indexée à un coût

    @++

  13. #13
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 239
    Points
    4 239
    Par défaut
    Ok... Je retiens que puisque j'ai déjà créer tous les index qui serviront lors des recherches sur la table principale, il n'est plus nécessaire de le faire sur la vue.

    Ai-je bien compris vos propos ? (j'ai parfois un peu de mal)

    Merci elsuket.
    Kropernic

  14. #14
    Expert éminent sénior
    Avatar de mikedavem
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2005
    Messages
    5 450
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Distribution

    Informations forums :
    Inscription : Août 2005
    Messages : 5 450
    Points : 12 891
    Points
    12 891
    Par défaut
    Exactement.

    ++

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Select d'une date en DATETIME
    Par mkaffel dans le forum SQL Procédural
    Réponses: 2
    Dernier message: 03/08/2006, 10h51
  2. [Dates] Comparaison date
    Par BenoitDenis dans le forum Langage
    Réponses: 16
    Dernier message: 29/03/2006, 13h50
  3. [VBA-E] Comparaison date / datetime
    Par dahu29 dans le forum Macros et VBA Excel
    Réponses: 9
    Dernier message: 15/03/2006, 13h12
  4. [Dates] problème Comparaison dates
    Par gwen-al dans le forum Langage
    Réponses: 4
    Dernier message: 06/01/2006, 11h24
  5. [SYBASE] Comparaison de deux datetime
    Par paf15 dans le forum Sybase
    Réponses: 1
    Dernier message: 17/04/2005, 16h51

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo