2017-10-12 1 views
-1

j'ai les 3 tableaux suivants:LEFT JOIN fonctionnalité dans un double joint (peut-être) requête avec WHERE

Clients AS c 
-------- 
ClientID, 
ClientGUID, 
InitializationDate, 
LastCheckin 

ClientServices AS cs 
--------------- 
ClientID, 
ServiceID, 
Status, 
Version 

Services AS s 
--------- 
ServiceID, 
Name, 
Description 

je dois construire une requête qui me donnera les résultats suivants:

s.Name, cs.Version 

J'ai besoin d'agir comme une jointure gauche, dans le sens où j'aimerais que tous les services s'affichent, que ce soit dans ClientServices ou non. La version sélectionnée s'affichera simplement sous la forme NULL dans ce cas.

J'ai essayé de faire quelques jointures simples, mais chaque combinaison de LEFT JOIN et JOIN que j'ai utilisé a abouti à SEULEMENT les ClientServices qui appartenaient à ce client. Un exemple:

SELECT s.`Name`, 
      cs.`Version` 
FROM  `Services` s LEFT JOIN ClientServices cs ON 
      s.`ServiceID` = cs.`ServiceID` 
      JOIN Clients c ON 
      cs.`ClientID` = c.`ClientID` 
WHERE  `ClientGUID`='thisisanewguid' 

j'ai pu enfin obtenir le résultat souhaité avec cette requête:

SELECT s.`Name`, 
      cs.`Version` 
FROM  `Services` s LEFT JOIN ClientServices cs 
      ON s.`ServiceID` = cs.`ServiceID` 
WHERE  cs.ClientID = (
          SELECT ClientID 
          FROM  Clients 
          WHERE  ClientGUID='thisisanewguid' 
         ) 
OR  cs.ClientID IS NULL 

mais je me sens comme si son un peu « aki ». Existe-t-il un meilleur moyen d'obtenir le même ensemble de résultats, mais sans effectuer plusieurs sélections dans une requête? (De préférence avec seulement les jointures, mais je ne suis pas sûr si c'est plus possible)

Exemple Data Set:

clients:

ClientID,   ClientGUID, InitializationDate, LastCheckin 
     1, 'xxxxxxxxxxxxxxxx',   10/10/2017, 10/12/2017 
     2, 'thisisanewguid',   05/23/2017, 10/12/2017 

ClientServices:

ClientID, ServiceID, Status, Version 
     1,   1,  1, '0.1' 
     2,   1,  1, '0.1' 
     2,   2,  1, '0.2' 

Services:

ServiceID,  Name,        Description 
     1, InITManager, 'Manages and updates all InIT services.' 
     2,  InITIAM,  'InIT's Inventory/Asset Management.' 
     3, InITTesting,        'testing' 

Résultat souhaité Set OU ClientGUID = 'thisisanewguid':

 Name, Version 
InITManager, '0.1' 
    InITIAM, '0.2' 
InITTesting, NULL 
+0

Voir https://meta.stackoverflow.com/questions/333952/why-should-i-provide-an-mcve-for-what-seems-to-me-to-be-a-very -simple-sql-query – Strawberry

+0

Une jointure à gauche produit une valeur nulle lorsqu'aucun résultat n'est trouvé et une jointure interne supprime la ligne si aucun enregistrement n'est trouvé. Vous commencez à la table s gauche rejoindre à cs..so cs null est valide et vous verrez les résultats de s qui n'ont pas d'entrée correspondante cs à ce stade. Vous vous joignez ensuite à c à partir de cs ... tous les zéros laissés par la première jointure à gauche sont maintenant filtrés lors de cette jointure. Avoir du sens? La jointure gauche suivie d'une jointure interne est auto-défaite. – Twelfth

+0

Cela a du sens, et j'ai pensé à cela après que ça n'a pas fonctionné, mais quand j'ai ensuite essayé deux "LEFT JOIN", ça ne marche toujours pas parce que je dois spécifier "WHERE c.ClientGUID" = 'thisisanewguid''.En fait, plus j'y pense, plus j'ai tendance à conclure que ma deuxième requête est la seule façon de le faire. – TheEggSample

Répondre

2

pour obatin le résultat que vous montriez en question vous pouvez utiliser la table gauche avec la jointure gauche sans la clause where pour la colonne impliquée id gauche rejoindre

SELECT s.`Name`, 
      cs.`Version` 
FROM  `Services` s 
LEFT JOIN ClientServices cs ON s.`ServiceID` = cs.`ServiceID` 
LEFT JOIN Clients c ON c.ClientID = cs.ClientID AND c.`ClientGUID`='thisisanewguid' 
+0

Avec cela, je n'aurais aucun moyen de spécifier 'WHERE ClientGUID = 'thisisanewguid'' – TheEggSample

+0

réponse mise à jour .. pour client rejoindre – scaisEdge

+0

Merci! Je n'ai jamais vraiment pensé ou je savais que vous pourriez utiliser 'AND' dans un JOIN. Merci encore. – TheEggSample

0

Salut pouvez-vous s'il vous plaît essayer la requête suivante

SELECT cs.Version, s.Name 
FROM ClientServices cs 
RIGHT JOIN Clients c ON c.ClientID = cs.ClientID 
RIGHT JOIN Services s ON s.ServiceID = cs.ServiceID 
+0

Cela a presque la fonctionnalité que je recherche ... Mais si j'ajoute 'WHERE c.ClientGUID = 'thisisanewguid'', alors je ne reçois que InITManager et InITIAM. – TheEggSample