Als u de tabelstructuur echt niet kunt wijzigen, kunt u waarschijnlijk het beste een van de oude lijsthacks gebruiken:
-
Gebruik een
JOIN
met 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 ;
-
Gebruik
LIKE
om de aanwezigheid van een specifieke serviceID-waarde in de knooppuntlijst te detecterenSELECT 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 ;
Zoals u echter al opmerkte, zou die kolom echt moeten worden genormaliseerd. Hoewel de bovenstaande methoden zouden moeten werken voor kleine datasets, hebben ze last van de gebruikelijke problemen bij het werken met "lijsten". Geen van beide methoden is erg indexvriendelijk en zal daarom niet goed schalen. Beide voeren ook tekenreeksvergelijkingen uit. Dus het kleinste verschil kan ervoor zorgen dat de matching mislukt. Bijvoorbeeld 1,4
zou overeenkomen met twee serviceID's, terwijl 1,(space)4
of 1,4.0
zou er maar één matchen.
Update op basis van opmerkingen:
Bij de tweede lezing weet ik niet zeker of het bovenstaande de precieze vraag beantwoordt die u stelt, maar het zou een goede basis moeten bieden om mee te werken ...
Als u niet langer een CSV-lijst wilt, gebruikt u gewoon een van de bovenstaande query's en voert u de afzonderlijke querykolommen uit zoals gewoonlijk. Het resultaat is één servicenaam per rij, dat wil zeggen:
server1 | Control Name One | Service Name 200
server1 | Control Name One | Service Name 50
..
Als u de door komma's gescheiden waarden wilt behouden, kunt u een <cfoutput group="..">
gebruiken. op de vraagresultaten. Aangezien de resultaten eerst op "Host" worden gerangschikt, zoiets als de onderstaande code. NB: Om "groep" goed te laten werken, moeten de resultaten worden besteld door Host
en je moet meerdere cfoutput
. gebruiken tags zoals hieronder weergegeven.
<cfoutput query="..." group="Host">
#Host# |
#ControlName# |
<cfoutput>
#ServiceName#,
</cfoutput>
<br>
</cfoutput>
Het resultaat zou er als volgt uit moeten zien:
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,
Update 2:
Ik was vergeten dat er een eenvoudiger alternatief is voor 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>