Jika Anda benar-benar tidak dapat mengubah struktur tabel, mungkin yang terbaik yang dapat Anda lakukan adalah salah satu peretasan daftar yang lama:
-
Gunakan
JOIN
dengan FIND_IN_SET(nilai, 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 ;
-
Gunakan
LIKE
untuk mendeteksi keberadaan nilai serviceID tertentu dalam daftar nodeSELECT 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 ;
Namun, seperti yang telah Anda catat bahwa kolom benar-benar harus dinormalisasi. Sementara metode di atas harus bekerja untuk kumpulan data kecil, mereka menderita masalah biasa bekerja dengan "daftar". Tidak ada metode yang sangat ramah indeks, dan akibatnya, tidak akan skala dengan baik. Juga, keduanya melakukan perbandingan string. Jadi perbedaan sekecil apa pun dapat menyebabkan pencocokan gagal. Misalnya, 1,4
akan cocok dengan dua ID layanan, sedangkan 1,(space)4
atau 1,4.0
hanya akan cocok dengan satu.
Pembaruan berdasarkan komentar:
Pada pembacaan kedua, saya tidak yakin jawaban di atas menjawab pertanyaan yang tepat yang Anda ajukan, tetapi itu harus memberikan dasar yang baik untuk bekerja dengan ...
Jika Anda tidak lagi menginginkan daftar CSV, cukup gunakan salah satu kueri di atas dan keluarkan kolom kueri individual seperti biasa. Hasilnya akan menjadi satu nama layanan per baris, yaitu:
server1 | Control Name One | Service Name 200
server1 | Control Name One | Service Name 50
..
Jika tidak, jika Anda perlu mempertahankan nilai yang dipisahkan koma, satu kemungkinan adalah menggunakan <cfoutput group="..">
pada hasil kueri. Karena hasilnya diurutkan oleh "Host" terlebih dahulu, kira-kira seperti kode di bawah ini. NB: Agar "grup" berfungsi dengan baik, hasilnya harus diurutkan oleh Host
dan Anda harus menggunakan beberapa cfoutput
tag seperti yang ditunjukkan di bawah ini.
<cfoutput query="..." group="Host">
#Host# |
#ControlName# |
<cfoutput>
#ServiceName#,
</cfoutput>
<br>
</cfoutput>
Hasilnya akan terlihat seperti ini:
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,
Pembaruan 2:
Saya lupa ada alternatif yang lebih sederhana untuk cfoutput group
di 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>