[SQL] un coup de main pour rouler mon join?

un coup de main pour rouler mon join? [SQL] - SQL/NoSQL - Programmation

Marsh Posté le 18-12-2005 à 12:25:13    

Salut,  
 
Je reprends le SQL après quelques années d'inactivité et j'avoue avoir un peu de mal à rouler ma requete...  
 
J'ai une table Adresses:  
id
nom
adresse
...
 
et une autre avec des Prix:
id
datetime                // la date à partir de laquelle le prix est valide
prix
 
Le but de la requete étant de retrouver le prix le plus récent pour chacune des adresses, le lien entre les deux étant l'id bien entendu.  
 
J'utilise MySQL 5.0.16
 
merci d'avance pour vos lumières  :hello:

Reply

Marsh Posté le 18-12-2005 à 12:25:13   

Reply

Marsh Posté le 18-12-2005 à 12:45:12    

"id" etant le lien entre les deux table?

Reply

Marsh Posté le 18-12-2005 à 12:55:30    

Berceker United a écrit :

"id" etant le lien entre les deux table?


+1 :heink:

Reply

Marsh Posté le 18-12-2005 à 13:00:58    

je suppose que prix.id reference adresse.id [:el g]

Reply

Marsh Posté le 18-12-2005 à 13:03:50    

chrisbk a écrit :

je suppose que prix.id reference adresse.id [:el g]


l'interet si le rapport est 1.1  :??: c'est pas un reproche  mais je pose la question

Reply

Marsh Posté le 18-12-2005 à 13:05:22    

Berceker United a écrit :

l'interet si le rapport est 1.1  :??: c'est pas un reproche  mais je pose la question


 
 
en 1.1, aucun, mais
 

Citation :

e but de la requete étant de retrouver le prix le plus récent pour chacune des adresses,


 
donc je suppose que pour une adresse tu peux avoir plusieurs prix
 

Reply

Marsh Posté le 18-12-2005 à 13:08:02    

donc order by [datetime] et c'est le premier rec.

Reply

Marsh Posté le 18-12-2005 à 14:13:15    

Berceker United a écrit :

donc order by [datetime] et c'est le premier rec.


 
Ben dis-donc moi qui croyait que j'aurais pas de réponse un dimanche :jap:
 
en effet ça semble très simple à première vue... quelques précisions, comme a bien supposé chrisbk le lien entre les deux tables est bien adresse.id = prix.id et pour chaque adresse on peut avoir n prix...
 
adresses  

id       lieu  
1        Bruxelles
2        Paris


prix

id       date          prix
1        20051217   0,567
1        20051215   0,456
2        20051213   0,613
2        20051217   0,666
2        20051130   0,654


 
La requete devrait me retourner:

id      nom         date            prix
1       Bruxelles   20051217     0,567
2       Paris        20051217     0,666


Reply

Marsh Posté le 18-12-2005 à 14:26:26    

SELECT * FROM adresse, prix WHERE adresse.id=prix.id ORDER BY date DESC
 
J'ai bon ?  :whistle:  J'ai codé à l'arrache.

Message cité 1 fois
Message édité par Berceker United le 18-12-2005 à 14:26:52
Reply

Marsh Posté le 18-12-2005 à 14:30:01    

jpense pas, la tu vas renvoyer trop de ligne, il veut qu'une ligne par adresse

Reply

Marsh Posté le 18-12-2005 à 14:30:01   

Reply

Marsh Posté le 18-12-2005 à 14:34:01    

Il faut faire la requete en deux temps alors. Il faut faire une sous requete. Dans la sous requete il place une requete qui permet de récupérer la date la plus proche avec un limite 1,1 ou 0,1 je me rappelle par ou sa commence


Message édité par Berceker United le 18-12-2005 à 14:34:58
Reply

Marsh Posté le 18-12-2005 à 14:59:43    

Pour moi ça doit être un truc du style  


SELECT s.id, s.lieu,  
( select p.prix
  from prix p
  where p.id = s.id
  order by p.id, p.date desc
  limit 1
)
from adresses s
where 1;


mais mySQL n'est pas d'accord...


Message édité par avander le 18-12-2005 à 15:01:04
Reply

Marsh Posté le 18-12-2005 à 15:57:03    

je pense que tu devrais le placer dans la clause where la sous requete.

Reply

Marsh Posté le 18-12-2005 à 17:29:10    

SELECT *  
FROM adresse, prix  
WHERE adresse.id=prix.id
AND PRIX >= (SELECT prix
      FROM adresse, prix
      WHERE adresse.id = prix.id);
 
 
à deuxième vue, manque peut etre une corrélation dans l'histoire.


Message édité par moi23372 le 18-12-2005 à 17:29:49
Reply

Marsh Posté le 18-12-2005 à 18:09:12    

avander a écrit :

Ben dis-donc moi qui croyait que j'aurais pas de réponse un dimanche :jap:
 
en effet ça semble très simple à première vue... quelques précisions, comme a bien supposé chrisbk le lien entre les deux tables est bien adresse.id = prix.id et pour chaque adresse on peut avoir n prix...
 
adresses  

id       lieu  
1        Bruxelles
2        Paris


prix

id       date          prix
1        20051217   0,567
1        20051215   0,456
2        20051213   0,613
2        20051217   0,666
2        20051130   0,654


 
La requete devrait me retourner:

id      nom         date            prix
1       Bruxelles   20051217     0,567
2       Paris        20051217     0,666



 
Moi je dirais un truc du genre :
 
SELECT * FROM adresse as a, prix as p WHERE a.id=p.id AND p.date=(SELECT p1.date FROM prix as p1 WHERE p1.id=p.id ORDER BY p1.date DESC LIMIT 1) GROUP BY a.id ASC


Message édité par joce le 18-12-2005 à 18:11:48
Reply

Marsh Posté le 18-12-2005 à 19:00:11    

And the winner is... joce! :jap:
 

SELECT *  
FROM adresse as a, prix as p  
WHERE a.id = p.id AND  
      p.date = ( SELECT p1.date  
                 FROM prix as p1  
                 WHERE p1.id=p.id  
                 ORDER BY p1.date DESC  
                 LIMIT 1)


 
J'ai enlevé le dernier order by inutile puisqu'il n'y a pas de doublons dans les adresses. Si vous voyez moyen d'optimiser la requete n'hésitez pas! Encore merci à tous.

Reply

Marsh Posté le 18-12-2005 à 19:35:36    

y a pas de doublon dans les adresses, mais il y en a dans les prix :??:

Reply

Marsh Posté le 18-12-2005 à 19:36:19    

Ouais mais tu fais ton group by sur a.id [:petrus dei]

Message cité 1 fois
Message édité par chrisbk le 18-12-2005 à 19:36:40
Reply

Marsh Posté le 18-12-2005 à 19:55:57    

chrisbk a écrit :

Ouais mais tu fais ton group by sur a.id [:petrus dei]


on s'en tape, a.id=p.id donc c'est pareil, il sera dupliqué par la jointure de toute façon, et le group by se fait sur le resultat de la jointure :o


Message édité par joce le 18-12-2005 à 19:57:28
Reply

Marsh Posté le 18-12-2005 à 19:59:43    

ah oui c'est ok parce que c'est le WHERE p.date= qui fait le boulot du group by :D


Message édité par joce le 18-12-2005 à 19:59:55
Reply

Marsh Posté le 18-12-2005 à 20:01:09    

'videmment gros noob [:dawao] retourne plutot jouer avec tes crayons de couleurs [:dawao]

Message cité 1 fois
Message édité par chrisbk le 18-12-2005 à 20:01:24
Reply

Marsh Posté le 18-12-2005 à 20:06:33    

chrisbk a écrit :

'videmment gros noob [:dawao] retourne plutot jouer avec tes crayons de couleurs [:dawao]


me demande qui a dit "Ouais mais tu fais ton group by sur a.id [:petrus dei]" :whistle: :D

Reply

Marsh Posté le 18-12-2005 à 21:09:14    

Histoire de faire quelque chose d'un peu différent, je pense que ca, ca fonctionne :
 
SELECT Adresses.*, Prix.prix
FROM adresses, Prix
WHERE Adresses.id=Prix.id
AND ROW(Prix.id, Prix.datetime) IN (
    SELECT id, MAX(datetime) AS dt_max
    FROM Prix
    GROUP BY id
  )  
 [:figti]


Message édité par mrbebert le 18-12-2005 à 21:10:26
Reply

Marsh Posté le 19-12-2005 à 14:34:24    

Pourquoi une sous requête, un simple group by sur id suffit ;)

Reply

Marsh Posté le 19-12-2005 à 14:41:28    

leflos5 a écrit :

Pourquoi une sous requête, un simple group by sur id suffit ;)

Sans sous-requête, ca me semble difficile, tu as un exemple :??:  
(à part le "max-concat trick", certes :D )

Reply

Marsh Posté le 19-12-2005 à 15:33:57    

Berceker United a écrit :

l'interet si le rapport est 1.1  :??: c'est pas un reproche  mais je pose la question


 
Si c'est historisé, l'interet existe :o


---------------
MZP est de retour
Reply

Marsh Posté le 19-12-2005 à 15:37:21    

Berceker United a écrit :

SELECT * FROM adresse, prix WHERE adresse.id=prix.id ORDER BY date DESC
 
J'ai bon ?  :whistle:  J'ai codé à l'arrache.


 
Pas vraiment. Il faut retourner tous les prix.
 
SELECT a.nom, a.adresse, p.prix
FROM adresse a INNER JOIN prix p ON (p.id = a.id)
WHERE p.datetime = (SELECT max(p1.datetime) FROM prix p1 WHERE p1.id = p.id)
 
Par contre, c'est pas terrible en perf.
 
Comment je suis grillé :o

Message cité 1 fois
Message édité par cinocks le 19-12-2005 à 15:39:48

---------------
MZP est de retour
Reply

Marsh Posté le 19-12-2005 à 16:41:02    

mrbebert a écrit :

Sans sous-requête, ca me semble difficile, tu as un exemple :??:  
(à part le "max-concat trick", certes :D )


 
JE vois pas où est le besoin si on est d'accord sur ce qu'on veut: le prix le plus récent sur un établissement donné?
 
 

cinocks a écrit :

Pas vraiment. Il faut retourner tous les prix.
 
SELECT a.nom, a.adresse, p.prix
FROM adresse a INNER JOIN prix p ON (p.id = a.id)
WHERE p.datetime = (SELECT max(p1.datetime) FROM prix p1 WHERE p1.id = p.id)
 
Par contre, c'est pas terrible en perf.
 
Comment je suis grillé :o


Je voispas où il a ditqu'il voulait tous les prix  :o  Il veut le dernier par maison on est d'accord :??:
 
Donc ça suffit amplement, pas besoin de surcharger...

Reply

Marsh Posté le 19-12-2005 à 16:48:48    

l'historisation est très importante dans le cas où on veut pouvoir regénérer des documents à postériori, ou refaire des calculs de valeur dans le temps.
 
exemple, je veux faire une simulation afin de déduire si mes relations avec mes fournisseurs évolue dans le bon sens ou non :
 
liste des prix de mes fournisseurs au 01/01/2005 et liste de ces mêmes prix aujourd'hui, afin de comparer s'ils ont augmenté, diminués ou sont restés stable.

Reply

Marsh Posté le 19-12-2005 à 17:03:07    

Bon alors les cracks ça donne quoi :P 2,3 sous requêtes pour faire le boulot d'une pauvre requête bien faite :whistle:

Reply

Marsh Posté le 19-12-2005 à 17:11:50    

leflos > nan, y'a pas moyen de faire ça en une seule requête sans passer par une sous-requête (ou alors j'imagine même pas la tronche de la requête, si bien-même ce serait possible)

Reply

Marsh Posté le 19-12-2005 à 17:33:20    

leflos5 a écrit :

JE vois pas où est le besoin si on est d'accord sur ce qu'on veut: le prix le plus récent sur un établissement donné?
 
 
 
Je voispas où il a ditqu'il voulait tous les prix  :o  Il veut le dernier par maison on est d'accord :??:
 
Donc ça suffit amplement, pas besoin de surcharger...


 
Tu as lu ma requete? :??:
 
Elle retourne le dernier prix connu par adresse. Je disais tous les prix en faisant reference aux adresse.


---------------
MZP est de retour
Reply

Marsh Posté le 19-12-2005 à 18:25:24    

Arjuna a écrit :

leflos > nan, y'a pas moyen de faire ça en une seule requête sans passer par une sous-requête (ou alors j'imagine même pas la tronche de la requête, si bien-même ce serait possible)


JE vais me lancer dans la vente par correspondance de requête alors :P
 
 

cinocks a écrit :

Tu as lu ma requete? :??:
 
Elle retourne le dernier prix connu par adresse. Je disais tous les prix en faisant reference aux adresse.


J'ai lu justement :) Et pour faire ça pas besoin de sous requête ;)
 
 
 
La bonne solution, certes pas complète mais la piste, est donnée depuis le début, mais c'est plus fort que certains de faire simple quand on peut faire compliquer et tartiner :p :whistle:

Reply

Marsh Posté le 19-12-2005 à 19:29:51    

cinocks a écrit :

Tu as lu ma requete? :??:
 
Elle retourne le dernier prix connu par adresse. Je disais tous les prix en faisant reference aux adresse.


et y'a pas un sous-select par hasard ? :o

Reply

Marsh Posté le 19-12-2005 à 19:30:25    

leflos5 a écrit :

JE vais me lancer dans la vente par correspondance de requête alors :P
 
 
 
J'ai lu justement :) Et pour faire ça pas besoin de sous requête ;)
 
 
 
La bonne solution, certes pas complète mais la piste, est donnée depuis le début, mais c'est plus fort que certains de faire simple quand on peut faire compliquer et tartiner :p :whistle:


j'attends de voir le truc...

Reply

Marsh Posté le 19-12-2005 à 19:31:59    

euh si c'est l'order by ton idée fulgurante elle n'est pas appropriée ;). Il veut pour chaque adresse obtenir le prix actuellement pratiqué.
 
L'order by va juste trier sur le datetime. Je ne vois pas l'interet de la chose. L'idée fonctionne si l'on ne veut recuperer qu'une seule adresse.
 
Mais si ce n'est pas ce cas de voulu, ca ne marche pas.


---------------
MZP est de retour
Reply

Marsh Posté le 19-12-2005 à 19:32:39    

Arjuna a écrit :

et y'a pas un sous-select par hasard ? :o


 
au hasard si. :D.
 
Mais il parait que l'on peut faire beaucoup plus simple. J'attends de voir.


Message édité par cinocks le 19-12-2005 à 19:33:27

---------------
MZP est de retour
Reply

Marsh Posté le 19-12-2005 à 19:34:24    

cinocks a écrit :

euh si c'est l'order by ton idée fulgurante elle n'est pas appropriée ;). Il veut pour chaque adresse obtenir le prix actuellement pratiqué.
 
L'order by va juste trier sur le datetime. Je ne vois pas l'interet de la chose. L'idée fonctionne si l'on ne veut recuperer qu'une seule adresse.
 
Mais si ce n'est pas ce cas de voulu, ca ne marche pas.


idem pour le having, car voulant retourner le prix, on ne peut pas grouper dessus

Reply

Marsh Posté le 19-12-2005 à 19:38:19    

tout à fait. Sinon on ne se ferait pas chier avec un subselect.
 
Mais un order by desc est plus approprié. D'ailleurs, on va supprimer les fonctions d'aggregats. Ca ne sert à rien.


---------------
MZP est de retour
Reply

Marsh Posté le 19-12-2005 à 19:43:22    

cinocks a écrit :

tout à fait. Sinon on ne se ferait pas chier avec un subselect.
 
Mais un order by desc est plus approprié. D'ailleurs, on va supprimer les fonctions d'aggregats. Ca ne sert à rien.


Toi tu commences par ravaler ton orgueil et tu admets que t'as tord, même si c'est juste une fois, l'erreur est humaine, hein ;)
 
Que tu saches pas comment faire sans sous requête (sub select comprends pas moi...) c'est une chose, que ça soit pas possible sans...
 
Donc tu restes humble et avant de devoir admettre de force je te laisse le temps depuis le début de trouver seul :)
 
J'adore toujours autant la confiture, c'est trop bon surtout de la voir sur les tartines des autres :p
 
edit: qui t'as parler d'order by, y'en a pas besoin en plus  :sarcastic:


Message édité par leflos5 le 19-12-2005 à 19:44:19
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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