Wenn Sie die Tabellenstruktur wirklich nicht ändern können, ist wahrscheinlich das Beste, was Sie tun können, einer der alten Listen-Hacks:
-
Verwenden Sie ein
JOIN
mit 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 ;
-
Verwenden Sie
LIKE
um das Vorhandensein eines bestimmten serviceID-Werts in der Knotenliste zu erkennenSELECT 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 ;
Wie Sie jedoch bereits bemerkt haben, sollte diese Spalte wirklich normalisiert werden. Während die obigen Methoden für kleine Datensätze funktionieren sollten, leiden sie unter den üblichen Problemen beim Arbeiten mit "Listen". Keine der beiden Methoden ist sehr indexfreundlich und lässt sich daher nicht gut skalieren. Außerdem führen beide Zeichenfolgenvergleiche durch. Der kleinste Unterschied kann also dazu führen, dass der Abgleich fehlschlägt. Beispiel:1,4
würde zwei serviceIDs entsprechen, wobei 1,(space)4
oder 1,4.0
würde nur mit einem übereinstimmen.
Aktualisierung basierend auf Kommentaren:
Beim zweiten Lesen bin ich mir nicht sicher, ob das Obige genau die Frage beantwortet, die Sie stellen, aber es sollte eine gute Grundlage bieten, um damit zu arbeiten ...
Wenn Sie keine CSV-Liste mehr möchten, verwenden Sie einfach eine der obigen Abfragen und geben Sie die einzelnen Abfragespalten wie gewohnt aus. Das Ergebnis ist ein Dienstname pro Zeile, dh:
server1 | Control Name One | Service Name 200
server1 | Control Name One | Service Name 50
..
Andernfalls, wenn Sie die durch Kommas getrennten Werte beibehalten müssen, besteht eine Möglichkeit darin, einen <cfoutput group="..">
zu verwenden auf die Abfrageergebnisse. Da die Ergebnisse zuerst nach "Host" geordnet werden, etwa wie im folgenden Code. Hinweis: Damit "Gruppe" ordnungsgemäß funktioniert, müssen die Ergebnisse nach Host
sortiert werden und Sie müssen mehrere cfoutput
verwenden Tags wie unten gezeigt.
<cfoutput query="..." group="Host">
#Host# |
#ControlName# |
<cfoutput>
#ServiceName#,
</cfoutput>
<br>
</cfoutput>
Das Ergebnis sollte so aussehen:
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,
Aktualisierung 2:
Ich habe vergessen, dass es eine einfachere Alternative zu cfoutput group
gibt 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>