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

Langage SQL Discussion :

requete SQL avec filtrage sur les derniers enregistrements


Sujet :

Langage SQL

  1. #1
    Nouveau membre du Club
    Inscrit en
    Mars 2004
    Messages
    40
    Détails du profil
    Informations forums :
    Inscription : Mars 2004
    Messages : 40
    Points : 36
    Points
    36
    Par défaut requete SQL avec filtrage sur les derniers enregistrements
    Bonjour,
    Voilà, je suis un peu perdu dans ma requete SQL.

    J'ai 2 tables: "annonce" et "suivi_prix" qui se décomposent ainsi:

    annonce

    id |surface | type_de_bien | localite
    --------------------------------------
    1 | 80 | 2 | 77
    7 | 70 | 2 | 77
    2 | 130 | 2 | 77

    suivi_prix

    id |prix | date
    -----------------------
    1 | 230 | 12-25-2008
    7 | 150 | 10-14-2008
    2 | 250 | 09-27-2007
    7 | 130 | 02-29-2009
    7 | 120 | 03-10-2009
    2 | 220 | 03-15-2008

    Je voudrais en fait pouvoir garder sur cette dernière table les prix les plus récents pour chaque id en fonction du type_de_bien, de la localite, et dont la surface n'est pas "0".
    Au final, il faudrait que j'obtienne ca, apres un filtrage sur localite=77 et type_de_bien=2 et surface <> de 0

    surface|prix
    -------------
    80 | 230 ----> dernier prix enregistré pour l'id 1
    70 | 120 ----> dernier prix enregistré pour l'id 7
    130 | 220 ----> dernier prix enregistré pour l'id 2

    Voilà la requete que j'ai pour le momment, qui fonctionne très bien, mais je bloque pour récuperer uniquement le dernier prix enregistré dans la table "suivi_prix:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    ("SELECT annonce.surface, suivi_prix.prix 
    FROM annonce 
    INNER JOIN suivi_prix ON annonce.id = suivi_prix.id 
    WHERE annonce.localite='$localite' 
      AND annonce.type_de_bien='$type_de_bien' 
      AND annonce.surface<>'0'") or die(mysql_error())
    Voilà, j'espère avoir été assez clair sur mon problème, merci d'avance pour votre aide.

  2. #2
    Rédacteur
    Avatar de jsd03
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Août 2008
    Messages
    1 221
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information

    Informations forums :
    Inscription : Août 2008
    Messages : 1 221
    Points : 6 506
    Points
    6 506
    Par défaut
    Bonjour,

    essaye

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    ("SELECT annonce.surface, suivi_prix.prix, max( suivi_prix.date) As valVmax
    FROM annonce 
    INNER JOIN suivi_prix ON annonce.id = suivi_prix.id 
    WHERE annonce.localite='$localite' 
      AND annonce.type_de_bien='$type_de_bien' 
      AND annonce.surface<>'0'") OR die(mysql_error())
    ou

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    ("SELECT annonce.surface, suivi_prix.prix
    FROM annonce 
    INNER JOIN suivi_prix ON annonce.id = suivi_prix.id 
    WHERE annonce.localite='$localite' 
      AND annonce.type_de_bien='$type_de_bien' 
      AND annonce.surface<>'0'
    AND suivi_prix.date = (SELECT max(date) from suivi_prix)") OR die(mysql_error())
    Mais la première sera plus rapide.

  3. #3
    Nouveau membre du Club
    Inscrit en
    Mars 2004
    Messages
    40
    Détails du profil
    Informations forums :
    Inscription : Mars 2004
    Messages : 40
    Points : 36
    Points
    36
    Par défaut
    malheureusement cela ne fonctionne pas,

    La première me retourne uniquement l'annonce la plus recente, quelque soit l'id, or ce que je souhaite c'est qu'elle me retourne chaque annonce la plus recente pour chaque id.


    La seconde ne me retourne rien du tout.

    Merci quand meme

  4. #4
    Rédacteur
    Avatar de jsd03
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Août 2008
    Messages
    1 221
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information

    Informations forums :
    Inscription : Août 2008
    Messages : 1 221
    Points : 6 506
    Points
    6 506
    Par défaut
    Ah ok il fallait être plus clair

    Ceci fera surement l'affaire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT annonce.surface, suivi_prix.prix, max( suivi_prix.date) As valVmax
    FROM annonce 
    INNER JOIN suivi_prix ON annonce.id = suivi_prix.id 
    WHERE annonce.localite='$localite' 
      AND annonce.type_de_bien='$type_de_bien' 
      AND annonce.surface<>'0'
    GROUP BY  annonce.id
    Il fallait juste rajouter GROUP BY annonce.id

  5. #5
    Expert confirmé Avatar de Cybher
    Homme Profil pro
    Consultant réseaux et sécurité
    Inscrit en
    Mai 2005
    Messages
    3 281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Consultant réseaux et sécurité
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 281
    Points : 4 644
    Points
    4 644
    Par défaut
    salut,

    ce n'est pas si "simple" que cela

    Je verrais plus quelque chose dans ce style

    - pour chaque id, on prend la date max :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Select  id, max(date) as d  from suivi_prix group by id
    - on fait une jointure pour récupérer les autre colonnes correspondant à ce critère :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Select ....
    suivi_prix Join (Select  id, max(date) as d  from suivi_prix group by id) temp
    On s.id=temp.id and s.dates = temp.d
    - pour arriver à la requête finale, on joint ensuite la table annonce pour récupérer la surface :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Select a.surface,prix, temp.d  
    from suivi_prix s 
    Join (Select  id, max(date) as d  from suivi_prix group by id) temp
    On s.id=temp.id and s.date = temp.d
    Join annonce a on a.id=s.id

  6. #6
    Nouveau membre du Club
    Inscrit en
    Mars 2004
    Messages
    40
    Détails du profil
    Informations forums :
    Inscription : Mars 2004
    Messages : 40
    Points : 36
    Points
    36
    Par défaut
    déslolé jsd03, mais ta solution ne fonctionne toujours pas, elle me retourne un tableau avec les dernieres date mais pas avec le prix correspondant à cette date, elle prend un autre prix.
    Merci quand meme d'avoir tenté de m'aider.

    Je pense que Cybher a peut etre la solution, ou du moins s'en rapproche très fortement, il faudra que je teste ce soir, car la je ne peux pas --> mais ca sent bon pour moi ,je croise les doigts

    donc si je prend ligne à ligne avec mes tables (de mon post initial), je devrai obtenir:

    SELECT id, max(date) AS d FROM suivi_prix GROUP BY id
    suivi_prix

    id |prix | date
    -----------------------
    1 | 230 | 12-25-2008
    7 | 120 | 03-10-2009
    2 | 220 | 03-15-2008

    bon après j'avoue que j'ai pas tous compris dans cette requete:

    SELECT ....
    JOIN (SELECT id, max(date) AS d FROM suivi_prix GROUP BY id) temp
    ON s.id=temp.id AND s.dates = temp.d
    pourrais tu expliquer en détail la partie soulignée sans vouloir abusé de ta gentillesse,merci ?

    meme la 3eme partie je comprend pas tout, lol, je crois que j'ai visé trop haut

    SELECT a.surface,prix, temp.d FROM suivi_prix s
    JOIN (SELECT id, max(date) AS d FROM suivi_prix GROUP BY id) temp
    ON s.id=temp.id AND s.date = temp.d
    JOIN annonce a ON a.id=s.id

    c'est quoi s. et a. , je pense que c'est annonce" et suivi_prix, mais es ce que je peux laisser en abregé dans la requête (j'en doute), ou as tu abrégé pour ne pas user le clavier

    Merci en tous cas à vous d'avoir pris le temps de me répondre

    cdt,
    yaume

  7. #7
    Expert confirmé Avatar de Cybher
    Homme Profil pro
    Consultant réseaux et sécurité
    Inscrit en
    Mai 2005
    Messages
    3 281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Consultant réseaux et sécurité
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 281
    Points : 4 644
    Points
    4 644
    Par défaut
    salut,

    pour donner quelques explications :
    s et a sont des alias, cela permet de nommer une table (et accessoirement cela évite de user le clavier comme tu le dis ) donc tu peux laisser comme cela sans soucis

    on reviens sur la partie "la plus difficile" pour toi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT s.prix, temp.d FROM suivi_prix s
    JOIN (SELECT id, max(date) AS d FROM suivi_prix GROUP BY id) temp
    ON s.id=temp.id AND s.date = temp.d
    comme tu l'as vu, la requête de jsd ne permet pas de retourner les bons prix
    ici, j'ai pris pour chaque id, la date max, j'apelle cette requête temp. je la joins à ma table suivi_prix sur les critères id et et date pour récupérer le prix correspondant à cet id et cette date

  8. #8
    Nouveau membre du Club
    Inscrit en
    Mars 2004
    Messages
    40
    Détails du profil
    Informations forums :
    Inscription : Mars 2004
    Messages : 40
    Points : 36
    Points
    36
    Par défaut
    Je crois que c'est cette partie que je n'arrive vraiment pas à comprendre


    SELECT ....
    suivi_prix JOIN (SELECT id, max(date) AS d FROM suivi_prix GROUP BY id) temp
    ON s.id=temp.id AND s.dates = temp.d
    Là:
    (SELECT id, max(date) AS d FROM suivi_prix GROUP BY id) temp
    ok, je récupère une table que j'appelle "temp" qui contient les lignes ayant la date la plus recente pour chaque id

    Après ce que je comprend pas c'est que je fais une jointure entre la table suivi_prix et la table "temp", alors que cette derniere vient de la table suivi_prix, je comprend pas l'interet de ca ?
    Es ce que je ne peux pas faire plus simple en faisant une jointure directement vers la table "annonce" ?, du genre:

    SELECT temp.id, s.prix, temp.d, a.surface FROM annonce a
    JOIN (SELECT id, max(date) AS d FROM suivi_prix s GROUP BY id) temp
    ON a.id=temp.id
    désolé, mais j'essaie juste de comprendre, je trouve ca plus interessant que de recopier sans comprendre.

  9. #9
    Expert confirmé Avatar de Cybher
    Homme Profil pro
    Consultant réseaux et sécurité
    Inscrit en
    Mai 2005
    Messages
    3 281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Consultant réseaux et sécurité
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 281
    Points : 4 644
    Points
    4 644
    Par défaut
    non, car tu as besoin du prix qui est dans la table suivi_prix

  10. #10
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    556
    Détails du profil
    Informations personnelles :
    Localisation : Laos

    Informations forums :
    Inscription : Mars 2003
    Messages : 556
    Points : 1 198
    Points
    1 198
    Par défaut
    Bonjour,

    Et pourtant il y a une grosse différence entre la nature de la table suivi_prix et pseudo-table temp...

    La table suivi_prix vous permet d'historiser les prix, ce qui sous entend que cette table s'alimente à chaque modification de prix... La table va donc naturellement croitre en fonction des saisies...

    la pseudo-table "temp" vous indiquera toujours la dernière date saisie par Id...
    Donc tant que dans la base il n'y a pas de nouvel Id... le nombre de ligne restera stable, c'est juste la valeur de date qui changera...

    Or par rapport à votre demande, la jointure est à faire sur la pseudo table et non sur la table suivi_prix... Car les jeux de résultat des 2 tables sont totalement différentes.

  11. #11
    Nouveau membre du Club
    Inscrit en
    Mars 2004
    Messages
    40
    Détails du profil
    Informations forums :
    Inscription : Mars 2004
    Messages : 40
    Points : 36
    Points
    36
    Par défaut
    Citation Envoyé par Cybher Voir le message
    non, car tu as besoin du prix qui est dans la table suivi_prix
    Alors peut etre que ca marcherait si je récuperai aussi le prix dans la table "temp":

    SELECT temp.id, temp.prix, temp.d, a.surface FROM annonce a
    JOIN (SELECT id, prix, max(date) AS d FROM suivi_prix GROUP BY id) temp
    ON a.id=temp.id

    Non ?

    Euh Ry_yo, si j'ai bien compris vous êtes un peu d'accord avec moi ?


    En tout cas merci à tous, tres sympas ce forum, ou les gens prennent le temps d'expliquer les choses

  12. #12
    Expert confirmé Avatar de Cybher
    Homme Profil pro
    Consultant réseaux et sécurité
    Inscrit en
    Mai 2005
    Messages
    3 281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Consultant réseaux et sécurité
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 281
    Points : 4 644
    Points
    4 644
    Par défaut
    non, cela ne fonctionnera pas

    voila pourquoi : tu groupes selon l'id jusque la tout va bien
    pour chaque id, tu prend la date max tout est toujours ok
    maintenant tu veux dire que tu prend le prix, oui mais quel prix? si tu ne lui précises pas, le SGBD ne peut pas avoir

    donc
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT id, prix, max(date) AS d FROM suivi_prix GROUP BY id
    est une hérésie puisque le SGBD doit faire un choix sur le prix... cette syntaxe planterait d'ailleurs sur la plupart des SGBD (seul mysql accepte cette syntaxe bizarre)

    donc une fois qu'on a notre couple (id, date(max)) on joint en fait avec la table suivi_prix sur l'id et la date pour récupérer le prix correspondant. En fait, cette jointure sert à récupérer le prix d'un id et d'une date donnée

    je ne sais pas si je suis très clair

  13. #13
    Nouveau membre du Club
    Inscrit en
    Mars 2004
    Messages
    40
    Détails du profil
    Informations forums :
    Inscription : Mars 2004
    Messages : 40
    Points : 36
    Points
    36
    Par défaut
    mea culpa, c'est bien la requete de cybher qui fonctionne parfaitement, il ne me reste plus qu'à comprendre pourquoi (j'ai vu ton nouveau message, mais mon cerveau n'a pas encore essayé de le décrypter ,lol)

    Donc la requete qui fonctionne:
    SELECT a.surface,prix, temp.d
    FROM suivi_prix s
    JOIN (SELECT id, max(date) AS d FROM suivi_prix GROUP BY id) temp
    ON s.id=temp.id AND s.date = temp.d
    JOIN annonce a ON a.id=s.id

    Maintenant il va falloir que je filtre sur la localite et le type de bien, j'avoue que j'ai du mal à savoir ou je vais placer mon WHERE localite='$localite'
    AND annonce.type_de_bien='$type_de_bien'

    En tous cas merci à tous pour votre aide.

  14. #14
    Nouveau membre du Club
    Inscrit en
    Mars 2004
    Messages
    40
    Détails du profil
    Informations forums :
    Inscription : Mars 2004
    Messages : 40
    Points : 36
    Points
    36
    Par défaut
    Bon ben je crois être arrivé a ce que je voulais exactement:

    SELECT a.surface,prix, temp.d, s.id FROM suivi_prix s JOIN (SELECT id, max(date) AS d FROM suivi_prix GROUP BY id) temp ON s.id=temp.id AND s.date = temp.d JOIN annonce a ON a.id=s.id WHERE localite='$localite' AND type_de_bien='$type_de_bien' AND surface<>'0'
    Ca a l'air de fonctionner, qu'en pensez vous ,? merci à vous tous !!

  15. #15
    Nouveau membre du Club
    Inscrit en
    Mars 2004
    Messages
    40
    Détails du profil
    Informations forums :
    Inscription : Mars 2004
    Messages : 40
    Points : 36
    Points
    36
    Par défaut
    si ,si Cybher, c'est très clair en fait ont "créé" une table avec les couples id et max(date), et ensuite on se sert de cette table "temporaire" pour faire réellement la requête voulu.

    Merci encore à tous de m'avoir aidé, et pris le temps d'expliquer.

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

Discussions similaires

  1. Requete SQL avec jointure sur trois tables
    Par pit2121 dans le forum Langage SQL
    Réponses: 1
    Dernier message: 19/05/2008, 23h07
  2. [SQL - Oracle 9i] Requete Sql avec filtre sur critere
    Par shaun_the_sheep dans le forum Oracle
    Réponses: 3
    Dernier message: 05/12/2007, 08h45
  3. [Excel/VBA] Requete SQL avec clause sur une suite de Cellule
    Par Myogtha dans le forum Macros et VBA Excel
    Réponses: 10
    Dernier message: 21/02/2007, 17h36
  4. requete sql avec between sur des champs de type Date
    Par ersoufiane dans le forum Langage SQL
    Réponses: 2
    Dernier message: 02/08/2006, 19h43
  5. [Access] requete sql avec condition sur date
    Par qeja dans le forum Langage SQL
    Réponses: 4
    Dernier message: 25/03/2006, 23h54

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