Subconsulta de selección SQL
-
07-07-2019 - |
Pregunta
Soy un poco nuevo en SQL y he encontrado el siguiente problema.
Tengo una tabla con detalles de la compañía que está unida a una tabla de contactos por un enqID.
Dentro de la tabla de contactos, hay 4 tipos diferentes de contactos que pueden tener o no una entrada. Estos se diferencian por un ctcTypID (1 - 4)
Me gustaría generar una consulta que contenga todos los registros de la compañía más un nombre de contacto para cada uno de los 4 tipos diferentes de contacto, todos en una fila.
Pensé que podría hacer esto usando subconsultas para cada uno de los diferentes contactos, pero parece que no puedo hacer que funcione, ya que no sé cómo escribir una cláusula de selección de subconsulta que haga referencia a su cláusula de selección principal (si ya ves lo que quiero decir!)
¿Es esto posible? Como he mencionado, soy bastante nuevo en SQL, ¡así que intenta no burlarte demasiado!
Gracias,
Steve
Solución
Algo así (suponiendo que esté utilizando SQL Server 2005 y versiones posteriores; desafortunadamente, no mencionó eso en su publicación original):
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
Necesita usar LEFT OUTER JOINs ya que puede que no haya una coincidencia, y al hacer esto, su consulta no será demasiado rápida en términos de rendimiento, pero es de esperar que funcione.
Marc
Otros consejos
Esto también debería funcionar. Evita unirse en la tabla de contactos varias veces.
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
Creo que está intentando utilizar SQL para algo para lo que no está diseñado. SQL es un lenguaje que le permite manipular y recuperar datos, también está tratando de usar SQL para formatear la salida de los datos recuperados, y creo que no debe hacer eso:
No debe intentar formatear (poner todos los contactos en una fila f.i.) los datos con SQL. Mi consejo es: simplemente use la consulta SQL más eficiente para recuperar los datos de la base de datos y formatee la salida (coloque los contactos en la misma fila) en otro idioma (C #, Delphi, PHP, lo que sea que esté usando para su aplicación).