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útSELECT 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 ;
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>