Si realmente no puede modificar la estructura de la tabla, probablemente lo mejor que puede hacer es uno de los trucos de la lista anterior:
-
Usa un
JOIN
con FIND_IN_SET(value, commaSeparatedString)SELECT n.Host, c.Name AS ControlName, s.Name AS ServiceName FROM node n LEFT JOIN control c ON c.controlID = n.controlID LEFT JOIN service s ON FIND_IN_SET(s.serviceID, n.serviceId) ORDER BY n.host, s.Name ;
-
Usa
LIKE
para detectar la presencia de un valor de ID de servicio específico dentro de la lista de nodosSELECT n.Host, c.Name AS ControlName, s.Name AS ServiceName FROM node n LEFT JOIN control c ON c.controlID = n.controlID LEFT JOIN service s ON CONCAT(',', n.serviceID,',') LIKE CONCAT('%,', s.serviceID,',%') ORDER BY n.host, s.Name ;
Sin embargo, como ya notó, esa columna realmente debería normalizarse. Si bien los métodos anteriores deberían funcionar para conjuntos de datos pequeños, sufren los problemas habituales de trabajar con "listas". Ninguno de los métodos es muy compatible con los índices y, como resultado, no se escalará bien. Además, ambos realizan comparaciones de cadenas. Entonces, la más mínima diferencia puede hacer que la coincidencia falle. Por ejemplo, 1,4
coincidiría con dos ID de servicio, mientras que 1,(space)4
o 1,4.0
coincidiría solo con uno.
Actualización basada en comentarios:
En la segunda lectura, no estoy seguro de que lo anterior responda la pregunta precisa que está haciendo, pero debería proporcionar una buena base para trabajar con...
Si ya no desea una lista CSV, simplemente use una de las consultas anteriores y genere las columnas de consulta individuales como de costumbre. El resultado será un nombre de servicio por fila, es decir:
server1 | Control Name One | Service Name 200
server1 | Control Name One | Service Name 50
..
De lo contrario, si necesita conservar los valores separados por comas, una posibilidad es usar un <cfoutput group="..">
sobre los resultados de la consulta. Dado que los resultados se ordenan primero por "Host", algo como el código a continuación. Nota: Para que "grupo" funcione correctamente, los resultados deben ordenarse por Host
y debe usar múltiples cfoutput
etiquetas como se muestra a continuación.
<cfoutput query="..." group="Host">
#Host# |
#ControlName# |
<cfoutput>
#ServiceName#,
</cfoutput>
<br>
</cfoutput>
El resultado debería verse así:
server1 | Control Name One | Service Name 200, Service Name 50, Service Name Four, Service Name One, Service Name Three, Service Name Two,
server2 | Control Name Two | Service Name 200, Service Name Four, Service Name Three, Service Name Two,
server3 | Control Name Two | Service Name 200, Service Name 50, Service Name Four, Service Name One, Service Name Three, Service Name Two,
server4 | Control Name Three | Service Name 200, Service Name 50, Service Name One, Service Name Two,
server5 | Control Name Three | Service Name Four, Service Name One,
Actualización 2:
Olvidé que hay una alternativa más simple a cfoutput group
en MySQL:GROUP_CONCAT
<cfquery name="qry" datasource="MySQL5">
SELECT n.Host, c.Name AS ControlName, GROUP_CONCAT(s.Name) AS ServiceNameList
FROM node n
LEFT JOIN control c ON c.controlID = n.controlID
LEFT JOIN service s ON FIND_IN_SET(s.serviceID, n.serviceId)
GROUP BY n.Host, c.Name
ORDER BY n.host
</cfquery>