Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Truy vấn SQL nhiều bảng, với nhiều phép nối và trường cột với danh sách được phân tách bằng dấu phẩy

Nếu bạn thực sự không thể sửa đổi cấu trúc bảng, có lẽ điều tốt nhất bạn có thể làm là một trong những cách hack danh sách cũ:

  • Sử dụng JOIN với FIND_IN_SET (giá trị, dấu phẩySeparatedString)

    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 ;

  • Sử dụng LIKE để phát hiện sự hiện diện của một giá trị serviceID cụ thể trong danh sách nút

    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

Tuy nhiên, như bạn đã lưu ý rằng cột thực sự nên được chuẩn hóa. Mặc dù các phương pháp trên sẽ hoạt động với các tập dữ liệu nhỏ, nhưng chúng vẫn gặp phải các vấn đề thông thường khi làm việc với "danh sách". Không có phương pháp nào là rất thân thiện với chỉ mục và kết quả là sẽ không mở rộng quy mô tốt. Ngoài ra, cả hai đều thực hiện so sánh chuỗi. Vì vậy, sự khác biệt nhỏ nhất có thể khiến việc khớp không thành công. Ví dụ:1,4 sẽ khớp với hai ID dịch vụ, trong khi 1,(space)4 hoặc 1,4.0 sẽ chỉ khớp với một.

Cập nhật dựa trên nhận xét:

Ở lần đọc thứ hai, tôi không chắc câu trả lời ở trên trả lời chính xác câu hỏi bạn đang hỏi, nhưng nó sẽ cung cấp cơ sở tốt để làm việc với ...

Nếu bạn không muốn danh sách CSV nữa, chỉ cần sử dụng một trong các truy vấn ở trên và xuất các cột truy vấn riêng lẻ như bình thường. Kết quả sẽ là một tên dịch vụ trên mỗi hàng, tức là:

   server1 | Control Name One | Service Name 200
   server1 | Control Name One | Service Name 50
   ..

Ngược lại, nếu bạn cần duy trì các giá trị được phân tách bằng dấu phẩy, một khả năng là sử dụng <cfoutput group=".."> trên kết quả truy vấn. Vì các kết quả được sắp xếp theo thứ tự của "Máy chủ lưu trữ" trước, một cái gì đó giống như mã bên dưới. NB: Để "nhóm" hoạt động bình thường, kết quả phải được sắp xếp theo thứ tự của Host và bạn phải sử dụng nhiều cfoutput như được hiển thị bên dưới.

 <cfoutput query="..." group="Host"> 
    #Host# |
    #ControlName# |
    <cfoutput>
      #ServiceName#,
    </cfoutput>
    <br>
 </cfoutput>

Kết quả sẽ như thế này:

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, 


Cập nhật 2:

Tôi quên rằng có một giải pháp thay thế đơn giản hơn cho cfoutput group trong 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. Làm cách nào để so sánh dữ liệu đầu vào với dữ liệu mysql với php / sql?

  2. MySql - giai đoạn dữ liệu gửi chậm

  3. Cơ sở dữ liệu SQL với số cột thay đổi

  4. Sự khác biệt giữa mysql.createConnection và mysql.createPool trong mô-đun Node.js MySQL là gì?

  5. Làm cách nào để lưu trữ dữ liệu XML vào cơ sở dữ liệu mysql? Tôi không muốn các phím nước ngoài như điên