Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
2925 connectés 

  FORUM HardWare.fr
  Programmation
  SQL/NoSQL

  Requête Sql - Trouver dates les plus proches

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Requête Sql - Trouver dates les plus proches

n°2187420
hush hush
je savais que ça te plairait
Posté le 24-04-2013 à 16:44:01  profilanswer
 

Bonjour,
Je me galère depuis ce midi sur des requêtes sql pour récupérer des données, et là, je m'avoue 20 culs.
 
J'ai une table qui ressemble à peu près à ça:
 
ID     Date     Argument
1   12/4/13    x
2   13/4/13    y
4   16/4/13    z
5   18/4/13    a
 
L'utilisateur va vouloir retrouver les ID/date et Argument pour une date donnée.
1er cas (déjà géré): il choisi une date existante-> imaginons qu'il cherche le 13/4/13, le recordset va lui retourner 2   13/4/13  y
2eme cas (c'est ce que j'essaye de faire)
Il choisi une date n'existant pas: le 15/4/13, du coup, le programme, qui est quand même sympa, va lui proposer les 2 dates autour: 13/4/13 et 16/4/13
 
Comment réussir à faire ça??
J'ai commencé par faire un :
"Select Max(Date) FROM maTable WHERE date<" & untrucimmondepourpasserlesdates
Cette requête est sensée me renvoyer la première date en dessous de celle demandée initialement
Sauf que comme vous pouvez le remarquer, je ne récupère que la date. Impossible de demander d'autres choses...
Je suis tombé sur des sites expliquant qu'il fallait imbriquer un select dans le premier
Et là, le bas blesse.
Je n'y arrive simplement pas :(
 
Si quelqu'un a une piste un tuto simple pour les requêtes "composées", je dis merci!
:jap:
 
EDIT: l'id de la table est une clé primaire auto. Les dates ne sont pas forcément entrées dans l'ordre, ainsi, je peux avoir IDd1>IDd2 avec DATEd1<DATEd2


Message édité par hush hush le 24-04-2013 à 17:02:25
mood
Publicité
Posté le 24-04-2013 à 16:44:01  profilanswer
 

n°2187421
x1fr
Posté le 24-04-2013 à 17:04:22  profilanswer
 

Un truc comme ca :

Code :
  1. Select * FROM maTable WHERE date = (Select Max(Date) FROM maTable WHERE date< XXXXX)
 


Tu peux peut être gérer les 2 cas avec une seule requête

 
Code :
  1. Select top 1 * FROM maTable WHERE date <= XXXXX)
  2. ORDER BY date desc
 

un truc dans le genre :
- Tu tries les entrées par date décroissantes, en te limitant à la date en paramètre.
- Tu ne retourne que la première ligne.
- Si une entrée existe pour la date, c'est elle qui sera retournée, et tu as ton cas 1
- Si ce n'est pas le cas, c'est la date précédente la plus proche qui est retournée, tu as ton cas 2

 

Par contre, ça ne gère pas le cas où il y aurait une date supérieure plus proche que la date précédente.

 

ps : le "TOP 1" c'est pour sql server, je crois que suivant le SGBD la syntaxe n'est pas la même (LIMIT sur mysql de mémoire)

Message cité 1 fois
Message édité par x1fr le 24-04-2013 à 17:04:46

---------------
Origin / PSN / Steam / Uplay : x1fr - bnet : Fab#2717
n°2187423
hush hush
je savais que ça te plairait
Posté le 24-04-2013 à 17:16:53  profilanswer
 

x1fr a écrit :

Un truc comme ca :

Code :
  1. Select * FROM maTable WHERE date = (Select Max(Date) FROM maTable WHERE date< XXXXX)


 
 
Tu peux peut être gérer les 2 cas avec une seule requête
 

Code :
  1. Select top 1 * FROM maTable WHERE date <= XXXXX)
  2. ORDER BY date desc


 
un truc dans le genre :
- Tu tries les entrées par date décroissantes, en te limitant à la date en paramètre.
- Tu ne retourne que la première ligne.
- Si une entrée existe pour la date, c'est elle qui sera retournée, et tu as ton cas 1
- Si ce n'est pas le cas, c'est la date précédente la plus proche qui est retournée, tu as ton cas 2
 
Par contre, ça ne gère pas le cas où il y aurait une date supérieure plus proche que la date précédente.
 
ps : le "TOP 1" c'est pour sql server, je crois que suivant le SGBD la syntaxe n'est pas la même (LIMIT sur mysql de mémoire)


:jap:
-J'avais pensé à faire une seule requête dans la même veine que ce que tu disais (me retourne la date précise ou la plus proche), mais comme tu le dis, on n'en récupère qu'une, Or, j'ai vraiment besoin de proposer l'autre aussi (la supérieur)
 
Une autre solution que j'avais envisagé était la suivante:
Extraire d'emblée les dates comprises entre datedemandée-5 et datedemandée+5 (car je considère qu'il ne peu pas y avoir plus de 5 jours entre 2 dates en base, ce qui doit être vrai, mais c'est pas tip top)
Il fallait ensuite faire un traitement en vba avec des tris (et ça, ça pue!)
Je préfère laisser faire ssql ce qu'il sait faire, et pareil pour vba.
 
Je sais que ce n'est pas optimum car là, j'éxecute au pire des cas 3 requêtes (la première qui ne me retourne rien, les 2 suivantes qui me retourne date inf et date sup)
 
Le code proposé en 1er marche tout à fait! Je viens de l'implémenter et ça tourne nickel :)
Merci beaucoup pour ton coup de pouce!


Message édité par hush hush le 24-04-2013 à 17:17:26
n°2187425
x1fr
Posté le 24-04-2013 à 17:25:59  profilanswer
 

Humm, autre proposition :
 

Code :
  1. Select top 1 * FROM maTable WHERE date <= XXXXX) ORDER BY date desc
  2. UNION
  3. Select top 1 * FROM maTable WHERE date >= XXXXX) ORDER BY date


 
Le UNION fait le tri sur les doublons à la manière d'un SELECT DISTINCT, donc si la date précise existe, cette requête ne retournera que la ligne voulue, sinon elle retourne les 2 lignes dont les 2 dates les plus proches, respectivement avant et après la date en paramètre.


---------------
Origin / PSN / Steam / Uplay : x1fr - bnet : Fab#2717
n°2187426
hush hush
je savais que ça te plairait
Posté le 24-04-2013 à 17:28:22  profilanswer
 

[:luc@s] Ouh toi!
ça me semble cool comme requête, j'implémente et je re :o

n°2187427
hush hush
je savais que ça te plairait
Posté le 24-04-2013 à 17:36:06  profilanswer
 

Moué...
Ma base est mal foutue en fait...
ça me renvoi à un problème que j'ai décidé de ne pas résoudre :o
En gros, mes dates sont enregistrées en date + heure
tant et si bien, (vu que je n'entre jamais l'heure dans la requête), que la requête ne trouve jamais vraiment la date exacte.
D'ailleurs, ma première requête comportait une condition d'encadrement (where date>=datedemandee AND date<datedemandee+1)
 
Sinon, ta dernière requête fonctionne tout à fait!
Maintenant, je dois décider s'il est plus simple de traiter systématiquement 2 réponses (datedemandee/dateprécédente OU datesuivante/dateprécédente)
ou de traiter en 2/3 requêtes
 
En tout cas, tu m'en enlève au moins une!


Message édité par hush hush le 24-04-2013 à 17:36:41
n°2187429
x1fr
Posté le 24-04-2013 à 17:41:57  profilanswer
 

C'est sur quel SGBD?

 

Tu dois pouvoir extraire uniquement des parties de ton champ date.
Par exemple sur SQL Server tu peux faire :

 
Code :
  1. DATEPART (year, date)
  2. DATEPART (month, date)
  3. DATEPART (day, date)
 

Qui te permettent de récupérer l'année, le mois et le jour d'un champ date, qu'il te suffirait de comparer 1 à 1 à ta date en paramètre (en applicant les mêmes fonctions sur le paramètre pour la comparaison)

 

edit : Sinon l'autre solution c'est au niveau de ton code de n'utiliser que la partie date de la variable. Par exemple en C# (je ne sais pas quel langage/sgbd tu utilises donc je continue avec mon exemple C#/SQL Serveur), pour récupérer la date, au lieu de faire DateTime.Now, tu fais DateTime.Now.Date, de cette manière tu récupère  24/04/2013 00:00:00 au lieu de l'heure actuelle.

Message cité 1 fois
Message édité par x1fr le 24-04-2013 à 17:45:08

---------------
Origin / PSN / Steam / Uplay : x1fr - bnet : Fab#2717
n°2187436
hush hush
je savais que ça te plairait
Posté le 24-04-2013 à 17:49:15  profilanswer
 

Arfghrgfff SGBD, j'ai su un jour ce que ça voulais dire :o
hmmm je suis sur excel/vba///Access
J'utilise les biblio DAO et OLE (je crois que la seconde n'a rien a voir, je ne sais plus)
Mes requêtes SQL sont entrées en vba dans des recordset que j'exécute et dont je récupère les résultats.
 
Le problème de datepart() c'est qu'elle ne renvois qu'un élément de la date, ce qui signifie que je dois l'executer 3 fois (jour, mois et année) pour chaque mention de la date...
ça risque de faire beaucoup de AND dans mes requêtes et des parenthèses que je ne saurais peut être pas gérer...
 
Voulant optimiser le nombre de connections à la base, je vais tout de même garder l'option requête qui renvoi 2 résultats, je les stock dans un variant vba, et du coup, j'aurai un petit traitement supplémentaire.
 
Cette solution me semble moins coûteuse qu'aller chercher comment expliquer à access qu'il peut ignorer l'heure...

n°2187440
hush hush
je savais que ça te plairait
Posté le 24-04-2013 à 17:57:15  profilanswer
 

x1fr a écrit :

C'est sur quel SGBD?
 
Tu dois pouvoir extraire uniquement des parties de ton champ date.
Par exemple sur SQL Server tu peux faire :
 

Code :
  1. DATEPART (year, date)
  2. DATEPART (month, date)
  3. DATEPART (day, date)


 
Qui te permettent de récupérer l'année, le mois et le jour d'un champ date, qu'il te suffirait de comparer 1 à 1 à ta date en paramètre (en applicant les mêmes fonctions sur le paramètre pour la comparaison)
 
edit : Sinon l'autre solution c'est au niveau de ton code de n'utiliser que la partie date de la variable. Par exemple en C# (je ne sais pas quel langage/sgbd tu utilises donc je continue avec mon exemple C#/SQL Serveur), pour récupérer la date, au lieu de faire DateTime.Now, tu fais DateTime.Now.Date, de cette manière tu récupère  24/04/2013 00:00:00 au lieu de l'heure actuelle.


le problème ne se pose pas à la récéption des données (l'heure ne me gène pas, au final, c'est l'id qui m'importe), c'est dans l'autre sens: expliquer à ma requête que 08/04/2013 17:15:32 est égal à 08/04/2013 00:00:00 (sous entendu car je lui communique seulement 08/04/2013)
 
J'ai peur qu'il soit bien trop compliqué de comparer des dates jour à jour, mois à mois et année à année
Trouver un truc simple qui arrive à comprendre que 01/01/2000 > 31/12/1999 en une seule ligne sql... ça me semble chaud

n°2187441
x1fr
Posté le 24-04-2013 à 17:57:26  profilanswer
 

SGBD c'est "Système de Gestion de Base de Données", donc Access dans ton cas.
J'imagine que le SQL utilisé doit être similaire à SQL Serveur alors.
 
Je n'ai pas compris quelle solution tu as sélectionné, mais en général pour ce qui touche à la base de données je pars du principe que je fais faire un maximum de traitement au SGBD et un minimum par le code du point de vue performance.
 
Si le problème d'avoir 3 Conditions pour filtrer sur la date au lieu d'une n'est autre qu'esthétique, à mon avis ça vaut le coup, une fois que la requête est pondue, tu n'a plus trop à y toucher ne principe.


---------------
Origin / PSN / Steam / Uplay : x1fr - bnet : Fab#2717
mood
Publicité
Posté le 24-04-2013 à 17:57:26  profilanswer
 

n°2187442
x1fr
Posté le 24-04-2013 à 17:59:23  profilanswer
 

Ah oui j'avais oublié que la comparaison de la date se fait avec des > et <, pas des égalités, du coup ça complexifie le truc

 

edit : http://office.microsoft.com/fr-fr/ [...] 28814.aspx
Ca pourrait peut être être utile


Message édité par x1fr le 24-04-2013 à 18:02:11

---------------
Origin / PSN / Steam / Uplay : x1fr - bnet : Fab#2717
n°2187445
hush hush
je savais que ça te plairait
Posté le 24-04-2013 à 18:03:56  profilanswer
 

Ze winner iz:

Code :
  1. Select top 1 * FROM maTable WHERE date <= XXXXX) ORDER BY date desc
  2. UNION
  3. Select top 1 * FROM maTable WHERE date >= XXXXX) ORDER BY date


Je trouve ça assez sexy en fait.
 

Citation :

Je n'ai pas compris quelle solution tu as sélectionné, mais en général pour ce qui touche à la base de données je pars du principe que je fais faire un maximum de traitement au SGBD et un minimum par le code du point de vue performance.


C'est un principe que j'essai d'appliquer aussi, tant que je peux!
Mais là, compte tenu du nombre de fois où cette requête sera utilisée (allez, une 30 aine de fois par jour), la taille des bdd (elles vont gonfler, mais globalement, il s'ajoute une date par jour ouvré), je pense que j'ai un niveau largement satisfaisant de perf (20/80 parreto tout ça :p)
 
Choisir la requête citée dans ce poste allège déjà pas mal mon code initial (je t'en remercie au passage), et je ne trouve pas ça si emmerdant d'avoir 5 lignes de codes derrière, en vba pour utiliser les résultats!
Encore merci pour ton aide!
 
EDIT: non, ce n'est pas qu'une question d'esthétique, comme tu l'a remarqué, pour des égalités, ça va (jour=jour AND mois=mois AND annee=annee), mais dès qu'il s'agit de inférieur/supérieur, ça doit sérieusement devenir complexe


Message édité par hush hush le 24-04-2013 à 18:05:41
n°2187457
sltpaulo
Posté le 24-04-2013 à 19:22:06  profilanswer
 


 
en sql si tu veux formater  tes dates tu écris ça :
 
 
donc dans ton cas  
DATE_FORMAT(NOW(),'%m-%d-%Y')
    Select top 1 * FROM maTable WHERE DATE_FORMAT(date,'%m-%d-%Y') <= XX-XX-XXXX) ORDER BY date desc
    UNION
    Select top 1 * FROM maTable WHERE DATE_FORMAT(date,'%m-%d-%Y') >= XX-XX-XXXX) ORDER BY date
 
 
 
après tu adapte comme tu veux, pour rpondre a ton problème de comparaison des dates

n°2187469
hush hush
je savais que ça te plairait
Posté le 24-04-2013 à 21:18:34  profilanswer
 

sltpaulo a écrit :


 
en sql si tu veux formater  tes dates tu écris ça :
 
 
donc dans ton cas  
DATE_FORMAT(NOW(),'%m-%d-%Y')
    Select top 1 * FROM maTable WHERE DATE_FORMAT(date,'%m-%d-%Y') <= XX-XX-XXXX) ORDER BY date desc
    UNION
    Select top 1 * FROM maTable WHERE DATE_FORMAT(date,'%m-%d-%Y') >= XX-XX-XXXX) ORDER BY date
 
 
 
après tu adapte comme tu veux, pour rpondre a ton problème de comparaison des dates


Merci pour le passage!!
J'essaye ça demain et fais un retour, mais ça m'a l'air cool :)
Je n'avais pas trouvé cette fonction quand le problème s'était posé,
Je découvre à peine les fonctions de "transformation" de la donnée (formats, calculs...)
A +

n°2187487
Oliiii
Posté le 25-04-2013 à 08:00:37  profilanswer
 

Essaye ca pour tes dates.
C'est pour SQL Server mais ca devrai fonctioner dans Access:

Code :
  1. SELECT CONVERT(date,GETDATE()) 'SQL2008+', CONVERT(DATETIME,FLOOR(CONVERT(FLOAT,GETDATE())))

Message cité 1 fois
Message édité par Oliiii le 25-04-2013 à 08:01:07
n°2187527
hush hush
je savais que ça te plairait
Posté le 25-04-2013 à 11:26:39  profilanswer
 

Hello tout le monde :)
Je viens vous faire un petit point après avoir planché sur mes requêtes depuis ce matin :o
 

sltpaulo a écrit :


 
en sql si tu veux formater  tes dates tu écris ça :
 
 
donc dans ton cas  
DATE_FORMAT(NOW(),'%m-%d-%Y')
    Select top 1 * FROM maTable WHERE DATE_FORMAT(date,'%m-%d-%Y') <= XX-XX-XXXX) ORDER BY date desc
    UNION
    Select top 1 * FROM maTable WHERE DATE_FORMAT(date,'%m-%d-%Y') >= XX-XX-XXXX) ORDER BY date
 
 
 
après tu adapte comme tu veux, pour rpondre a ton problème de comparaison des dates


J'ai essayé avec Date_Format, ça me retourne une erreur de définition de la fonction. Soit il me manque une référence dans mon vba, soit il existe une autre fonction pour access.
J'utilise la fonction FORMAT(date,'mm\/dd\/yyyy') pour formater l'input (date à chercher),
Je l'ai essayée sur les dates de mes tables dans la requête (exemple: format(matable.date,'mm\/dd\/yyyy')). ça passe dans la requête mais les résultats sont débiles.
A mon avis, je me plante sur le second argument.

Oliiii a écrit :

Essaye ca pour tes dates.
C'est pour SQL Server mais ca devrai fonctioner dans Access:

Code :
  1. SELECT CONVERT(date,GETDATE()) 'SQL2008+', CONVERT(DATETIME,FLOOR(CONVERT(FLOAT,GETDATE())))



Merci pour le coup de pouce, mais je n'ai pas du tout réussi à intégrer ce truc dans mes requêtes...
 
J'avoue que j'ai été assez brouillon dans mon travail, du coup, j'ai perdu quelques anciennes requêtes :/
Celle que j'ai là, est fonctionnelle:

Code :
  1. "SELECT top 1 * FROM environment WHERE env_date = (SELECT Min(env_date) FROM environment WHERE (environment.env_Date>Format(#" & vDate & "#,'mm\/dd\/yyyy')) AND environment.NomP=""OFF"" ) UNION SELECT top 1 * FROM environment WHERE env_date = (SELECT Max(env_date) FROM environment WHERE (environment.env_Date<Format(#" & vDate & "#,'mm\/dd\/yyyy')) AND environment.NomP=""OFF"" )"


 
Si je demande une date existante:
La requête me retourne en 1er, la date précédente, puis la date demandée
 
Si je demande une date qui n'existe pas mais qui est encadrée par deux autres dates
Elle me retourne en 1er, la date précédente, et en 2d, la date suivante.
 
Je peux me dépatouiller avec ça, en post traitement vba, mais ça me saoul de savoir que je peux obtenir soit: 1 seule date, lorsque celle demandée est trouvée, soit deux dates, lorsque la date demandée n'existe pas.
 
Pour en revenir à ma requête, en la "cassant", ça me donne ça:
 
SELECT top 1 *
FROM environment WHERE
env_date = (
   SELECT Min(env_date) FROM environment WHERE (environment.env_Date>Format(#" & vDate & "#,'mm\/dd\/yyyy')) AND environment.NomP=""OFF"" )
   UNION
   SELECT top 1 * FROM environment WHERE env_date = (
   SELECT Max(env_date) FROM environment WHERE (environment.env_Date<Format(#" & vDate & "#,'mm\/dd\/yyyy')) AND environment.NomP=""OFF"" )
 
Il me semble qu'elle déconne un peu: l'avant dernière ligne n'est-elle pas superflue?? Je m'emmèle les pinceaux à la remasteriser, mais je continue de me galérer, je voulais juste vous faire un petit point :)
(rappel: cette requête est injectée dans un recordset sous vba dans excel :/)

n°2187666
Oliiii
Posté le 26-04-2013 à 08:25:39  profilanswer
 

si tu changes les < et > par <= et >= ca ne devrai plus te retourner qu'une seule ligne si la date existe, le UNION enleve les lignes identique.

n°2187687
hush hush
je savais que ça te plairait
Posté le 26-04-2013 à 12:26:35  profilanswer
 

Edit: En fait non, ça marche mal :/
 
Yep, j'avais pensé à cette modif
Sinon:
 [:wark0]  
I win! SQL is my bitch!!
Après pas mal de tests, déjà je me suis rendu compte que j'avais mal "cassé" la requête, (cf post plus haut),
Bref, j'en ai chier avec la fonction format, dont je ne connais pas encore vraiment les subtilités (surtout sur la question des formats utilisés entre access, excel, et le système)
 
Voilà donc la tête de la dernière requête qui fonctionne! (je l'ai cassée volontairement pour en faciliter la lecture)
La clé? Bah la fonction Int qui arrondi la date en base puis je reformate à l'aide de format.
Valà,
Merci beaucoup beaucoup pour la mobilisation, en espérant que ça décoincera certaines personnes à l'avenir :p

Code :
  1. SELECT top 1 * FROM environment WHERE Format(Int(env_date),'mm\/dd\/yyyy') = (SELECT Min(Format(Int(env_date),'mm\/dd\/yyyy')) FROM environment WHERE (Format(Int(env_date),'mm\/dd\/yyyy')>=Format(#" & vDate & "#,'mm\/dd\/yyyy')) AND environment.NomP=""OFF"" )
  2. Union
  3. SELECT top 1 * FROM environment WHERE Format(Int(env_date),'mm\/dd\/yyyy') = (SELECT Max(Format(Int(env_date),'mm\/dd\/yyyy')) FROM environment WHERE (Format(Int(env_date),'mm\/dd\/yyyy')<=Format(#" & vDate & "#,'mm\/dd\/yyyy')) AND environment.NomP=""OFF"" )


Message édité par hush hush le 26-04-2013 à 12:37:26
n°2187698
hush hush
je savais que ça te plairait
Posté le 26-04-2013 à 13:35:50  profilanswer
 

[:panzani gino]  
Je crois que cette fois, c'est bon:
En fait, la fonction format retourne une chaine de caractères...
Avec l'emmelage de pinceaux à cause des conventions de dates, ça chie dans la colle.
Et là, je me suis souvenu qu'un bon moyen de bosser sur les date est de les passer sous format: yyyymmdd
C'est ce que j'ai fait, et ça roule apparement bien (n'hésitez pas revenir au cas où finalement non, ça ne marche plus :o)
Le truc, c'est qu'il faut transformer l'input en amont et injecter directement un string sous format yyyymmdd, pour éviter qu'access interprête mal les dates
Valà,
C'était fastidieux, mais finalement, c'est bon :)

n°2197466
hush hush
je savais que ça te plairait
Posté le 15-07-2013 à 09:53:50  profilanswer
 

Hello all!
Je déterre ce topic où la communauté hfr m'avait aidé à monter une requête dans une requête :o
Depuis peu, j'ai un comportement très bizarre...
 
Pour rappelle, je demande à acces de me rechercher une date. En retour j'attends:
-La date et les champs associés si elle existe dans la table
-sinon, les deux dates les plus proches, avant et après cette date (et les champs associés).
 
Voici la requête incriminée :o
 

Citation :


SELECT Top 1 *  
FROM table1 WHERE format(date,'yyyymmdd') <= "20100515" AND nomP = "OFF" ORDER BY date DESC
Union
SELECT Top 1 *
FROM table1 WHERE format(date,'yyyymmdd') >= "20100515" AND nomP = "OFF" ORDER BY date  ASC


 
Pour la clareté de l'exemple, j'ai copié collé ma requête sql avec un argument. Sinon, je l'utilise dans vba avec des variables.
Je l'ai d'ailleurs répliquée en sql directement dans la bdd acces et le problème est bien présent.
 
En gros:
Je demande une date qui existe: la requête me sort 2 recordset: le bon et la fin de mois
Je demande une date qui n'existe pas: la requête me sort 2 recordset: la date précédente... et la fin de mois.
 
Ce qui est dingue c'est qu'en coupant la requête en deux:

Citation :

SELECT Top 1 *  
FROM table1 WHERE format(date,'yyyymmdd') <= "20100515" AND nomP = "OFF" ORDER BY date DESC


dans une requête et

Citation :

SELECT Top 1 *
FROM table1 WHERE format(date,'yyyymmdd') >= "20100515" AND nomP = "OFF" ORDER BY date  ASC


dans une autre, j'obtiens bien les résultats escomptés...
ie: si la date existe, les deux requêtes me sortent le même résultat,
si elle n'existe pas, chacune me renvoi la date la plus proche précédant et suivant celle demandée...
Je crois que c'est l'union qui merde. pourquoi? no lo sé :(


Message édité par hush hush le 15-07-2013 à 10:29:39
n°2197485
poulpeleac​h
Octopus paradisi
Posté le 15-07-2013 à 11:35:13  profilanswer
 

Euh, donc, là, en clair, ton probleme c'est que tu obtiens le fin du mois au lieu de la date sup la plus proche, c'est ca?

n°2197486
Fender
♪♫♪♫♪♫♪
Posté le 15-07-2013 à 11:36:06  profilanswer
 

le problème c'est que chez moi, ça marche parfaitement ta requête :D
Tu as vraiment une date correspondant à la fin du mois dans tes données, ou cette fin de mois sort de nulle part ?

Message cité 1 fois
Message édité par Fender le 15-07-2013 à 11:39:49
n°2197491
hush hush
je savais que ça te plairait
Posté le 15-07-2013 à 11:41:06  profilanswer
 

poulpeleach a écrit :

Euh, donc, là, en clair, ton probleme c'est que tu obtiens le fin du mois au lieu de la date sup la plus proche, c'est ca?


Yup
J'ai tenté un truc: j'ai inversé l'ordre des requêtes de l'union, et là, ça me sors la première date entrée :/ (en gros, rien à voir...)

Fender a écrit :

le problème c'est que chez moi, ça marche parfaitement ta requête :D
Tu as vraiment une date correspondant à la fin du mois dans tes requêtes, ou cette fin de mois sort de nulle part ?


Oui, ça me sors un id existant (structure de ma table: id(clé)|Date (au format: dd/mm/aaaa hh:mm:ss)|Argument1|Argument2)
Bon, derrière c'est lié en cascade à un tas d'autre truc...

n°2197494
Fender
♪♫♪♫♪♫♪
Posté le 15-07-2013 à 11:46:12  profilanswer
 

sinon, au cas où ce serait un truc bizarre dans tes données ou dans access, tu peux essayer un truc de ce genre :
SELECT Top 2 *
FROM table1
order by abs(format(date,'yyyymmdd')-"20110512" );
Le seul inconvénient est que t'auras toujours 2 résultats même quand la date existe...

n°2197495
Fender
♪♫♪♫♪♫♪
Posté le 15-07-2013 à 11:48:25  profilanswer
 

sinon, du coup, c'est bizarre, chezmoiçamarche.com avec ta solution, donc je vois pas bien d'où peut provenir le problème
 
mais donc, essaie ma solution et gère ailleurs dans ton code de virer l'enregistrement inutile lorsque la date existe :spamafote:

n°2197496
Fender
♪♫♪♫♪♫♪
Posté le 15-07-2013 à 11:51:17  profilanswer
 

ah merde, non, ça marche pas, ça va te ramener 2 dates du même côté si elles sont trop proches :D

n°2197497
hush hush
je savais que ça te plairait
Posté le 15-07-2013 à 11:53:25  profilanswer
 

[:delarue5]  
J'ai testé:
Date existante: me retourne la date existante et la précédente (ordre chronologique)
Date "manquante": me retourne... 3 résultats :o (genre là j'ai demandé le 28/05/2011, ça me renvoi 27/26 et 30 mai 2011 :/ :/ :/)

n°2197498
poulpeleac​h
Octopus paradisi
Posté le 15-07-2013 à 11:54:19  profilanswer
 

hush hush a écrit :


Yup
J'ai tenté un truc: j'ai inversé l'ordre des requêtes de l'union, et là, ça me sors la première date entrée :/ (en gros, rien à voir...)


 

hush hush a écrit :


Oui, ça me sors un id existant (structure de ma table: id(clé)|Date (au format: dd/mm/aaaa hh:mm:ss)|Argument1|Argument2)
Bon, derrière c'est lié en cascade à un tas d'autre truc...


 
 
Tu peux voir ce que donne :  
 
 
 
(
 
SELECT TOP 1  Format([date],'yyyymmdd') AS DateTxt
FROM table1  
WHERE (((Format([date],'yyyymmdd'))<="20100515" ))
ORDER BY Format([date],'yyyymmdd') DESC
 
)
 
union
(
SELECT TOP 1  Format([date],'yyyymmdd') AS DateTxt
FROM table1  
WHERE (((Format([date],'yyyymmdd'))>="20100515" ))
ORDER BY Format([date],'yyyymmdd') ASC
 
)
 
 
?  
 
( ajouté un format dans le order by )  
Je me demande si y a pas une incohérence possible entre le fait que ta clause order by soit sur le champ date "brut" et la clause where sur la version texte.

Message cité 1 fois
Message édité par poulpeleach le 15-07-2013 à 11:56:39
n°2197500
hush hush
je savais que ça te plairait
Posté le 15-07-2013 à 11:58:08  profilanswer
 

Fender a écrit :

sinon, du coup, c'est bizarre, chezmoiçamarche.com avec ta solution, donc je vois pas bien d'où peut provenir le problème
 
mais donc, essaie ma solution et gère ailleurs dans ton code de virer l'enregistrement inutile lorsque la date existe :spamafote:


C'est ce que je voulais éviter en faisant une seule requête.
Du coup, je crois que je vais rester sur le split de la première requête...
Ce qui fait 2 requêtes à chaque fois,
A moins que je teste après la première, si j'ai ma date, je passe à la suite du code, sinon, je complète ma variable du résultat de la seconde requête.
 
Mais je trouve fondamentalement débile de faire tourner 2 requêtes (donc 2 connections à la base) pour un truc qui devrait pouvoir être fait par une seule requête.
Y a moyen que ça vienne du format de la date en base (qui une date complète, avec l'heure), mais ça malheureusement, je ne peux absolument pas le changer
 
Sans compter que chez toi, ça marche, et que ça a marché chez moi pendant pas mal de temps (je ne sais pas ce qui a changé depuis  :o :o (enfin, si, j'ai compacté une paire de fois la bdd vu que je me chiais dans l'alimentation), enfin bref.

n°2197504
hush hush
je savais que ça te plairait
Posté le 15-07-2013 à 12:03:23  profilanswer
 

poulpeleach a écrit :


Tu peux voir ce que donne :  
(
 
SELECT TOP 1  Format([date],'yyyymmdd') AS DateTxt
FROM table1  
WHERE (((Format([date],'yyyymmdd'))<="20100515" ))
ORDER BY Format([date],'yyyymmdd') DESC
 
)
 
union
(
SELECT TOP 1  Format([date],'yyyymmdd') AS DateTxt
FROM table1  
WHERE (((Format([date],'yyyymmdd'))>="20100515" ))
ORDER BY Format([date],'yyyymmdd') ASC
 
)
 
 
?  
 
( ajouté un format dans le order by )  
Je me demande si y a pas une incohérence possible entre le fait que ta clause order by soit sur le champ date "brut" et la clause where sur la version texte.


Ton Select ne récupérer que les dates, hors, j'ai besoin de tous les arguments en sortie (d'où le select *) :(
Et quand j'ORDER par format(date,'...'), ça bug car l'order se fait sur les arguments du recordset...
 
 
 
Edit:
Pour la postérité, j'ai testé en ajoutant , * et ça marche!!
:)
On approche de la solution :o enfin je crois


Message édité par hush hush le 15-07-2013 à 12:08:03
n°2197507
hush hush
je savais que ça te plairait
Posté le 15-07-2013 à 12:12:54  profilanswer
 

Bon.
Au risque de me faire lyncher :o, je crois que j'ai trouvé la faille.
Je ne mettais pas de parenthèses, et je crois que c'est ce qui faisait bugger ma requête de mayrde.
J'implémente ça dans mon code + test avant de crier victoire, mais ma requête initiale marche beaucoup mieux en séparant les select top 1 * à l'aide de parenthèses...
Fuck, je ne pensais pas que c'était aussi important :o

n°2197666
Oliiii
Posté le 16-07-2013 à 08:27:44  profilanswer
 

En théorie ça l'est pas, mais la on parle d'Access hein :)

mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  SQL/NoSQL

  Requête Sql - Trouver dates les plus proches

 

Sujets relatifs
Requête SQL : Même occurence dans une colonne[access 2003] - Incrémentation de Dates
Importer un fichier ACCESS dans SQL SERVERUn Submit qui soit effectue une requete sql soit ouvre une pop up
Trouver la 1ere ligne vide d'un tableau et écrire dans les cellules[SQL] Requete date
SOS formule excel avec datesCascade de requête sql pour un système d'archivage [résolu]
Plus de sujets relatifs à : Requête Sql - Trouver dates les plus proches


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR