Se davvero non puoi modificare la struttura della tabella, probabilmente il meglio che puoi fare è uno dei vecchi hack delle liste:
-
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
per rilevare la presenza di un valore ServiceID specifico all'interno dell'elenco dei nodiSELECT 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 ;
Tuttavia, come hai già notato, quella colonna dovrebbe davvero essere normalizzata. Mentre i metodi sopra dovrebbero funzionare per piccoli set di dati, soffrono dei soliti problemi di lavorare con "liste". Nessuno dei due metodi è molto compatibile con gli indici e, di conseguenza, non si ridimensiona bene. Inoltre, entrambi eseguono confronti di stringhe. Quindi la minima differenza potrebbe far fallire la corrispondenza. Ad esempio, 1,4
corrisponderebbe a due serviceID, mentre 1,(space)4
o 1,4.0
corrisponderebbe solo a uno.
Aggiornamento basato sui commenti:
In seconda lettura, non sono sicuro che quanto sopra risponda alla domanda precisa che stai ponendo, ma dovrebbe fornire una buona base per lavorare con ...
Se non desideri più un elenco CSV, utilizza semplicemente una delle query precedenti e genera come al solito le singole colonne di query. Il risultato sarà un nome di servizio per riga, ovvero:
server1 | Control Name One | Service Name 200
server1 | Control Name One | Service Name 50
..
In caso contrario, se è necessario preservare i valori separati da virgola, una possibilità è utilizzare un <cfoutput group="..">
sui risultati della query. Poiché i risultati sono ordinati prima per "Host", qualcosa come il codice seguente. NB: Affinché "gruppo" funzioni correttamente, i risultati devono essere ordinati da Host
e devi usare più cfoutput
tag come mostrato di seguito.
<cfoutput query="..." group="Host">
#Host# |
#ControlName# |
<cfoutput>
#ServiceName#,
</cfoutput>
<br>
</cfoutput>
Il risultato dovrebbe assomigliare a questo:
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,
Aggiornamento 2:
Dimenticavo che esiste un'alternativa più semplice a cfoutput group
in 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>