Sous-requête SQL Select
-
07-07-2019 - |
Question
Je connais un peu SQL et j'ai rencontré le problème suivant.
J'ai une table contenant les détails de la société et qui est jointe à une table de contact par un enqID.
Dans la table des contacts, il existe 4 types de contacts différents qui peuvent ou non avoir une entrée. Ceux-ci sont différenciés par un ctcTypID (1-4)
Je souhaite créer une requête comportant tous les enregistrements de la société, ainsi qu'un nom de contact pour chacun des 4 types de contact différents, le tout sur une ligne.
Je pensais pouvoir le faire en utilisant des sous-requêtes pour chacun des différents contacts, mais je n'arrive pas à le faire fonctionner, car je ne sais pas comment écrire une clause select de sous-requête qui référence sa clause parent select (si vous voyez ce que je veux dire!)
Est-ce même possible? Comme je l'ai mentionné, SQL est relativement nouveau pour moi, alors essayez de ne pas trop vous moquer!
Merci,
Steve
La solution
Quelque chose comme (en supposant que vous utilisez SQL Server 2005 et versions ultérieures - malheureusement, vous ne l'avez pas mentionné dans votre message d'origine):
SELECT
c.CompanyName,
c1.ctcTypID, c1.ContactName,
c2.ctcTypID, c2.ContactName,
c3.ctcTypID, c3.ContactName,
c4.ctcTypID, c4.ContactName
FROM
CompanyTable c
LEFT OUTER JOIN
ContactTable c1 ON c.enqID = c1.enqID AND c1.ctcTypID = 1
LEFT OUTER JOIN
ContactTable c2 ON c.enqID = c2.enqID AND c2.ctcTypID = 2
LEFT OUTER JOIN
ContactTable c3 ON c.enqID = c3.enqID AND c3.ctcTypID = 3
LEFT OUTER JOIN
ContactTable c4 ON c.enqID = c4.enqID AND c4.ctcTypID = 4
Vous devez utiliser LEFT OUTER JOINs car il peut ne pas y avoir de correspondance et, ce faisant, votre requête ne sera pas très rapide en termes de performances - mais cela devrait fonctionner, espérons-le.
Marc
Autres conseils
Cela devrait également fonctionner. Évite de rejoindre la table de contact plusieurs fois.
SELECT
CompanyTable.CompanyName,
MAX(CASE WHEN ContactTable.ctcTypID = 1 THEN ContactTable.ContactName END) AS ContactName1,
MAX(CASE WHEN ContactTable.ctcTypID = 2 THEN ContactTable.ContactName END) AS ContactName2,
MAX(CASE WHEN ContactTable.ctcTypID = 3 THEN ContactTable.ContactName END) AS ContactName3,
MAX(CASE WHEN ContactTable.ctcTypID = 4 THEN ContactTable.ContactName END) AS ContactName4
FROM CompanyTable,
LEFT JOIN ContactTable
ON ContactTable.enqID = CompanyTable.enqID AND ContactTable.ctcTypID IN (1,2,3,4)
GROUP BY
CompanyTable.CompanyName
Je pense que vous essayez d'utiliser SQL pour quelque chose pour lequel il n'est pas conçu. SQL est un langage qui vous permet de manipuler et d'extraire des données. Vous essayez également d'utiliser SQL pour formater la sortie des données extraites, et je pense que vous ne devriez pas le faire:
Vous ne devez pas essayer de formater (en plaçant tous les contacts sur une seule ligne f.i.) les données avec SQL. Mon conseil est: utilisez simplement la requête SQL la plus performante pour récupérer les données de la base de données et formatez la sortie (placez les contacts sur la même ligne) dans un autre langage (C #, Delphi, PHP, tout ce que vous utilisez pour votre application).