Précédent   Forum des professionnels en informatique > Bases de données > MS SQL-Server > Développement
Développement Forum d'entraide sur le Transact-SQL, le CLR, les procédures stockées, les triggers, les requêtes SQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 23/01/2012, 14h34   #1
Membre Expert
 
Avatar de Kropernic
 
Homme
Analyste / Programmeur
Inscription : juillet 2006
Messages : 1 309
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 29
Localisation : Belgique

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

Informations forums :
Inscription : juillet 2006
Messages : 1 309
Points : 1 019
Points : 1 019
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 :
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 :
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 est déconnecté   Envoyer un message privé Réponse avec citation 01
Vieux 23/01/2012, 14h54   #2
Responsable SQL Server

 
Avatar de mikedavem
 
Homme David BARBARIN
Expert SQL Server
Inscription : août 2005
Messages : 3 726
Détails du profil
Informations personnelles :
Nom : Homme David BARBARIN
Localisation : France, Haute Savoie (Rhône Alpes)

Informations professionnelles :
Activité : Expert SQL Server
Secteur : Conseil

Informations forums :
Inscription : août 2005
Messages : 3 726
Points : 6 851
Points : 6 851
Bonjour,

Code :
1
2
3
SELECT *
FROM maTable
WHERE maColonneDateTime BETWEEN '2012-01-05' AND '2012-01-05 23:59:59'
ou encore

Code :
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 :
1
2
3
SELECT *
FROM maTable
WHERE CAST(maColonneDateTime AS DATE) = '2012-01-05';
++
mikedavem est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 23/01/2012, 14h55   #3
Modérateur
 
Homme Fabien
Ingénieur d'études en décisionnel
Inscription : septembre 2008
Messages : 5 688
Détails du profil
Informations personnelles :
Nom : Homme Fabien
Âge : 34
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études en décisionnel
Secteur : Arts - Culture

Informations forums :
Inscription : septembre 2008
Messages : 5 688
Points : 10 435
Points : 10 435
Envoyer un message via ICQ à Waldar Envoyer un message via Skype™ à Waldar
Il suffit d'utiliser des comparaisons au lieu d'une égalité.
Avis personnel, je préfère convertir mes constantes en date :
Code :
1
2
3
4
SELECT *
  FROM maTable
 WHERE maColonneDateTime >= convert(datetime, '2012-01-05', 121)
   AND maColonneDateTime <  convert(datetime, '2012-01-06', 121)
__________________
Email : http://scr.im/waldar
Waldar est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/01/2012, 15h13   #4
Membre Expert
 
Avatar de Kropernic
 
Homme
Analyste / Programmeur
Inscription : juillet 2006
Messages : 1 309
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 29
Localisation : Belgique

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

Informations forums :
Inscription : juillet 2006
Messages : 1 309
Points : 1 019
Points : 1 019
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 :
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 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/01/2012, 15h27   #5
Modérateur
 
Homme Fabien
Ingénieur d'études en décisionnel
Inscription : septembre 2008
Messages : 5 688
Détails du profil
Informations personnelles :
Nom : Homme Fabien
Âge : 34
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études en décisionnel
Secteur : Arts - Culture

Informations forums :
Inscription : septembre 2008
Messages : 5 688
Points : 10 435
Points : 10 435
Envoyer un message via ICQ à Waldar Envoyer un message via Skype™ à Waldar
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.
__________________
Email : http://scr.im/waldar
Waldar est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/01/2012, 15h31   #6
Membre Expert
 
Avatar de Kropernic
 
Homme
Analyste / Programmeur
Inscription : juillet 2006
Messages : 1 309
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 29
Localisation : Belgique

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

Informations forums :
Inscription : juillet 2006
Messages : 1 309
Points : 1 019
Points : 1 019
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 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/01/2012, 15h35   #7
Responsable SQL Server

 
Avatar de mikedavem
 
Homme David BARBARIN
Expert SQL Server
Inscription : août 2005
Messages : 3 726
Détails du profil
Informations personnelles :
Nom : Homme David BARBARIN
Localisation : France, Haute Savoie (Rhône Alpes)

Informations professionnelles :
Activité : Expert SQL Server
Secteur : Conseil

Informations forums :
Inscription : août 2005
Messages : 3 726
Points : 6 851
Points : 6 851
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.

++
mikedavem est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 23/01/2012, 15h37   #8
Membre Expert
 
Avatar de Kropernic
 
Homme
Analyste / Programmeur
Inscription : juillet 2006
Messages : 1 309
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 29
Localisation : Belgique

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

Informations forums :
Inscription : juillet 2006
Messages : 1 309
Points : 1 019
Points : 1 019
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 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/01/2012, 15h46   #9
Modérateur
 
Homme Fabien
Ingénieur d'études en décisionnel
Inscription : septembre 2008
Messages : 5 688
Détails du profil
Informations personnelles :
Nom : Homme Fabien
Âge : 34
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études en décisionnel
Secteur : Arts - Culture

Informations forums :
Inscription : septembre 2008
Messages : 5 688
Points : 10 435
Points : 10 435
Envoyer un message via ICQ à Waldar Envoyer un message via Skype™ à Waldar
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.
__________________
Email : http://scr.im/waldar
Waldar est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/01/2012, 15h46   #10
Responsable SQL Server

 
Avatar de mikedavem
 
Homme David BARBARIN
Expert SQL Server
Inscription : août 2005
Messages : 3 726
Détails du profil
Informations personnelles :
Nom : Homme David BARBARIN
Localisation : France, Haute Savoie (Rhône Alpes)

Informations professionnelles :
Activité : Expert SQL Server
Secteur : Conseil

Informations forums :
Inscription : août 2005
Messages : 3 726
Points : 6 851
Points : 6 851
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.

++
mikedavem est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/01/2012, 15h51   #11
Membre Expert
 
Avatar de Kropernic
 
Homme
Analyste / Programmeur
Inscription : juillet 2006
Messages : 1 309
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 29
Localisation : Belgique

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

Informations forums :
Inscription : juillet 2006
Messages : 1 309
Points : 1 019
Points : 1 019
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 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/01/2012, 16h17   #12
Modérateur

 
Avatar de elsuket
 
Homme Nicolas Souquet
Administrateur de base de données
Inscription : janvier 2005
Messages : 4 674
Détails du profil
Informations personnelles :
Nom : Homme Nicolas Souquet
Âge : 30
Localisation : Thaïlande

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

Informations forums :
Inscription : janvier 2005
Messages : 4 674
Points : 8 741
Points : 8 741
Bonjour,

Citation:
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

@++
__________________
En bases de données relationnelles SQL, il n'y a ni tableaux, ni enregistrements, ni champs: il y a des tables, des lignes et des colonnes.
Blog | Profil| Consulter ou télécharger les fichiers d'aide de SQL Server, des versions 2000 à 2012
elsuket est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 23/01/2012, 16h22   #13
Membre Expert
 
Avatar de Kropernic
 
Homme
Analyste / Programmeur
Inscription : juillet 2006
Messages : 1 309
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 29
Localisation : Belgique

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

Informations forums :
Inscription : juillet 2006
Messages : 1 309
Points : 1 019
Points : 1 019
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 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/01/2012, 16h28   #14
Responsable SQL Server

 
Avatar de mikedavem
 
Homme David BARBARIN
Expert SQL Server
Inscription : août 2005
Messages : 3 726
Détails du profil
Informations personnelles :
Nom : Homme David BARBARIN
Localisation : France, Haute Savoie (Rhône Alpes)

Informations professionnelles :
Activité : Expert SQL Server
Secteur : Conseil

Informations forums :
Inscription : août 2005
Messages : 3 726
Points : 6 851
Points : 6 851
Exactement.

++
mikedavem est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 20h09.


 
 
 
 
Partenaires

Hébergement Web