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 :

Jointure avec une seule ligne


Sujet :

Langage SQL

  1. #1
    Membre régulier
    Profil pro
    Dév FrontEnd
    Inscrit en
    Avril 2005
    Messages
    239
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Dév FrontEnd

    Informations forums :
    Inscription : Avril 2005
    Messages : 239
    Points : 114
    Points
    114
    Par défaut Jointure avec une seule ligne
    Bonjour,

    J'aimerais faire une jointure entre deux tables et n'avoir en retour qu'une seule ligne, même s'il y a plusieurs lignes correspondantes dans la seconde table, et avec une condition pour trouver laquelle retourner.

    Pour bien me faire comprendre (car je suis pas sûr d'être très clair ), voici un exemple :

    J'ai une table "personnes" et une table "voitures" (qui possède un champ "personne_id", clé étrangère pointant sur personnes.id).
    Je voudrais retrouver toutes les personnes présentes dans la base et pour chacune avoir la voiture lui appartenant, avec la date d'achat la plus récente.

    Pas sûr que ce soit faisable avec le JOIN seul. Mais sait-on jamais !

    Merci d'avance.

  2. #2
    Membre expérimenté
    Homme Profil pro
    Ingenieur de recherche - Ecologue
    Inscrit en
    Juin 2003
    Messages
    1 157
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingenieur de recherche - Ecologue

    Informations forums :
    Inscription : Juin 2003
    Messages : 1 157
    Points : 1 414
    Points
    1 414
    Par défaut
    bonjour


    non ce n'est pas tres clair

    la requete de test, et un exemple de donnees en retour serait le bienvenu


    et quel est le SGBD ?

  3. #3
    Membre régulier
    Profil pro
    Dév FrontEnd
    Inscrit en
    Avril 2005
    Messages
    239
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Dév FrontEnd

    Informations forums :
    Inscription : Avril 2005
    Messages : 239
    Points : 114
    Points
    114
    Par défaut
    Ok.
    Alors, pas de requêtes car justement je n'ai aucune idée de comment faire.
    Le SGBD est MySQL, en version 5.

    Mes tables :
    Personnes (id, nom, naissance)
    Voitures (id, nom, date_achat, personne_id)

    J'ai par exemple les données suivantes :
    Personne : 1, Pontus, 01/01/1980
    
    Voiture  : 1, C1, 02/05/2011, 1
    Voiture  : 2, C2, 03/01/2010, 1
    J'aimerais que ma requête me donne la personne 1 (Pontus) avec la voiture 1 (C1), soit la voiture acheté le plus récemment.
    Et la même chose pour chaque personne de la table Personnes ...

    Est-ce plus clair ?
    Comme je ne suis pas sûr que ce que je souhaite soit possible, au pire, j'aimerais n'avoir qu'une ligne par personne, même si cette personne a acheté plusieurs voitures : quel type de jointure utiliser alors ?

  4. #4
    Membre éprouvé
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    956
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 956
    Points : 1 199
    Points
    1 199
    Par défaut
    Bonjour,
    Voilà une requete, elle est un peu compliquée parce que j'ai considéré qu'une personne pouvait acheter deux voitures le même jour, dans ce cas j'ai pris une voiture arbitrairement.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    select P.id idPersonne, p.nom NomPersonne, p.naissance, vF.id idVoiture,vF.nom nomVoiture, vf.date_achat
    from Personnes P
    inner join 
    	(select vm.personne_id, max(vm.date_achat) as date_dernier_achat
    		from Voiture vm
    		group by vm.personne_id
    	) V1
    	on P.id=v1.personne_id
    inner join	
    	(select v3.personne_id, date_achat, max(V3.id) as id_derniere_voiture_achetee
    		from date_achat v3
    		group by v3.personne_id,date_achat
    	) V2
    	on v1.personne_id=V2.personne_id
    	and V1.date_dernier_achat=v2.date_achat
    inner join date_achat VF
    	on VF.personne_id=V2.personne_id
    	and VF.id=id_derniere_voiture_achetee
    Cela doit se simplifier énormément avec les fonctions de fenêtrage.
    A+
    Soazig

  5. #5
    Membre émérite Avatar de Drizzt [Drone38]
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2004
    Messages
    1 001
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Directeur de projet

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 001
    Points : 2 453
    Points
    2 453
    Par défaut
    Avec du fenetrage sous Oracle :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    with 
      personne as (select 1 id, 'P1' nom from dual union all
                  select 2, 'P2' from dual),
      voiture as (select 'C1' voiture, to_date('02/05/2011','DD/MM/YYYY') dte, 1 id_p from dual union all
                  select 'C2', to_date('03/01/2010','DD/MM/YYYY'), 1 from dual union all
                  select 'C4', to_date('02/05/2011','DD/MM/YYYY'), 1 from dual union all
                  select 'C2', to_date('02/05/2010','DD/MM/YYYY'), 2 from dual union all
                  select 'C3', to_date('02/05/2011','DD/MM/YYYY'), 2 from dual)
    select
        p.nom,
        max(v.voiture) keep(dense_rank first order by v.dte desc) voiture
    from personne p
    left join voiture v on v.id_p = p.id
    group by p.nom;
    Résultat:

    P1 C4
    P2 C3

  6. #6
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 453
    Points : 18 394
    Points
    18 394
    Par défaut
    Citation Envoyé par Drizzt [Drone38] Voir le message
    Avec du fenetrage sous Oracle
    En fait ici, il n'y a pas de fenêtrage, c'est la fonction FIRST sous sa forme agrégée classique. Elle existe aussi avec son extension PARTITION BY, mais pas nécessaire dans ce cas-là.
    Je me suis fait avoir aussi il y a quelques temps !
    Par contre, l'auteur étant sous MySQL, je doute que ça l'aide vraiment.

  7. #7
    Membre émérite Avatar de Drizzt [Drone38]
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2004
    Messages
    1 001
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Directeur de projet

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 001
    Points : 2 453
    Points
    2 453
    Par défaut
    C'est vrai bonne remarque. J'ai tendance à mettre un peu trop de choses sous l'appelation fenêtrage

  8. #8
    Expert éminent sénior
    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 801
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 801
    Points : 34 063
    Points
    34 063
    Billets dans le blog
    14
    Par défaut
    Quelle est, pour chaque personne, la dernière voiture qu'il a achetée ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT p.id, MAX(v.date_achat) AS dernier_achat
    FROM Personne p
    LEFT OUTER JOIN Voiture v ON v.personne_id = p.id
    GROUP BY p.id
    Quelle est la voiture correspondant à cette date d'achat pour chaque personne ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    SELECT tmp.nom AS nom_personne, 
        v1.nom AS nom_voiture,
        v1.date_achat
    FROM Voiture v1
    INNER JOIN 
    (
        SELECT p.id, p.nom, MAX(v.date_achat) AS dernier_achat
        FROM Personne p
        LEFT OUTER JOIN Voiture v ON v.personne_id = p.id
        GROUP BY p.id, p.nom
    ) tmp 
        ON tmp.id = v1.personne_id
        AND tmp.dernier_achat = v1.date_achat

Discussions similaires

  1. Réponses: 2
    Dernier message: 14/03/2013, 11h39
  2. extraire une partie de chaine avec une seule ligne de commande sed
    Par kinkichin dans le forum Shell et commandes GNU
    Réponses: 6
    Dernier message: 07/07/2009, 11h28
  3. Réponses: 3
    Dernier message: 06/11/2007, 12h16
  4. jointure qui retourne tout sur une seule ligne
    Par Ralfman68 dans le forum Requêtes
    Réponses: 9
    Dernier message: 12/10/2007, 22h52
  5. Plusieures infos sur une seule ligne avec ou sans tableau
    Par Him dans le forum Balisage (X)HTML et validation W3C
    Réponses: 5
    Dernier message: 17/03/2006, 15h16

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