2009-12-22 5 views
3

J'ai 3 tables:SELECT valeurs DISTINCTS après un JOIN

Vehicle: vehicle_id, vehicle_type 
1, motorcycle 
2, car 
3, van 

Owners: person_id, vehicle_id, date_bought 
1, 1, 2009 
1, 2, 2008 
2, 3, 2009 
2, 1, 2005 

Je veux afficher une liste de tous les noms de véhicules. Si le person_id = 1, date_bought doit également être retourné.

Je pensais que je voudrais commencer par ceci:

SELECT * FROM vehicles 
LEFT JOIN Owners USING (vehicle_id) 

qui retourne ceci:

1, 1, motorcycle, 2009 
1, 2, car, 2008 
2, 3, van, 2009 
2, 1, motorcycle, 2005 

Cependant, je peux pas réduire cela à le résultat nécessaire. Si j'utilise DISTINCT(car_id), il n'y a pas de changement car je choisis déjà des identifiants de voiture distincts avant le JOIN; ils ne sont pas distincts après la jointure. Si j'utilise WHERE person_id = 1, j'enlève les 2 dernières lignes et toute référence à la camionnette a disparu. Si j'utilise GROUP BY car_id, les première et dernière rangées sont combinées mais le date_bought pour la moto est choisi arbitrairement. Ce que je veux est la suivante:

1, 1, motorcycle, 2009 
1, 2, car, 2008 
, 3, van, 

Je dois exiger une pièce d'identité de voiture distincte, mais cela se produit avant que la jointure et n'a donc aucun effet. Comment puis-je obtenir l'unicité avec le JOIN?

Répondre

5

Vous devez inclure la restriction sur l'ID de personne dans votre jointure et utiliser une jointure externe. Les jointures externes sont utilisées lorsque vous souhaitez renvoyer des informations même s'il n'y a aucun enregistrement dans la table à laquelle vous vous joignez. Essayez

SELECT person_id, vehicles.* 
FROM vehicles 
LEFT OUTER JOIN Owners on vehicles.vehicle_id = owners.vehicle_id 
and person_id = 1 
+0

Cela fonctionne parfaitement. Merci beaucoup! –

2

Cela devrait revenir ce que vous avez inscrit comme résultat attendu:

SELECT DISTINCT 
      o.person_id, 
      v.vehicle_id, 
      v.vehicle_type, 
      o.date_bought 
    FROM VEHICLES v 
LEFT JOIN OWNERS o ON o.vehicle_id = v.vehicle_id 
LEFT JOIN (SELECT t.vehicle_id, 
        MAX(t.date_bought) 'max_date_bought' 
      FROM OWNERS t 
     GROUP BY t.vehicle_id) x ON x.vehicle_id = o.vehicle_id 
           AND x.max_date_bought = o.date_bought 
    WHERE o.person_id IS NULL 
     OR o.person_id = 1 

Soyez conscients qu'en raison de la jointure gauche, les colonnes PROPRIÉTAIRES retourneront NULL s'il n'y a pas vehicle_id correspondant à la Table PROPRIÉTAIRES.

Questions connexes