Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

SQL meminta beberapa tabel, dengan beberapa gabungan dan bidang kolom dengan daftar yang dipisahkan koma

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 node

    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 CONCAT(',', n.serviceID,',') LIKE CONCAT('%,', s.serviceID,',%') ORDER BY n.host, s.Name ;

SQLFiddle

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>



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Mengembalikan JSON tidak berfungsi dengan benar

  2. Bagaimana mengatasi InnoDB:Tidak dapat mengunci kesalahan ./ibdata1 mysql?

  3. Mengapa Rails mengabaikan Rollback dalam transaksi bersarang (semu)?

  4. Permintaan SQL LIKE gagal - kesalahan fatal dalam pernyataan yang disiapkan

  5. beberapa kueri tabel yang sama tetapi di kolom yang berbeda mysql