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

Sự cố SQL:mối quan hệ một đến nhiều và mô hình EAV

Câu trả lời ngắn gọn cho câu hỏi của bạn là không, không có cấu trúc đơn giản nào trong MySQL để đạt được kết quả mà bạn đang tìm kiếm.

Nhưng có thể cẩn thận (cẩn thận) tạo ra một truy vấn như vậy. Đây là một ví dụ, tôi tin tưởng bạn sẽ có thể giải mã nó. Về cơ bản, tôi đang sử dụng các truy vấn con tương quan trong danh sách đã chọn, cho mỗi thuộc tính mà tôi muốn trả về.

SELECT t.id
     , t.name
     , t.nickname

     , ( SELECT v1.attribute_value 
           FROM team_information v1 
           JOIN attributes a1
             ON a1.id = v1.attribute_id AND a1.attribute_name = 'city'
          WHERE v1.team_id = t.id ORDER BY 1 LIMIT 1
       ) AS city

     , ( SELECT v2.attribute_value
           FROM team_information v2 JOIN attributes a2
             ON a2.id = v2.attribute_id AND a2.attribute_name = 'captain'
          WHERE v2.team_id = t.id ORDER BY 1 LIMIT 1
       ) AS captain

     , ( SELECT v3.attribute_value
           FROM team_information v3 JOIN attributes a3
             ON a3.id = v3.attribute_id AND a3.attribute_name = 'f_number'
          WHERE v3.team_id = t.id ORDER BY 1 LIMIT 1
       ) AS f_number

  FROM teams t
 ORDER BY t.id

Đối với các thuộc tính 'đa giá trị', bạn phải kéo từng phiên bản của thuộc tính một cách riêng biệt. (Sử dụng LIMIT để chỉ định xem bạn đang truy xuất cái đầu tiên, cái thứ hai, v.v.)

     , ( SELECT v4.attribute_value
           FROM team_information v4 JOIN attributes a4
             ON a4.id = v4.attribute_id AND a4.attribute_name = 'nickname'
          WHERE v4.team_id = t.id ORDER BY 1 LIMIT 0,1
       ) AS nickname_1st

     , ( SELECT v5.attribute_value
           FROM team_information v5 JOIN attributes a5
             ON a5.id = v5.attribute_id AND a5.attribute_name = 'nickname'
          WHERE v5.team_id = t.id ORDER BY 1 LIMIT 1,1
       ) AS nickname_2nd

     , ( SELECT v6.attribute_value
           FROM team_information v6 JOIN attributes a6
             ON a6.id = v6.attribute_id AND a6.attribute_name = 'nickname'
          WHERE v6.team_id = t.id ORDER BY 1 LIMIT 2,1
       ) AS nickname_3rd

Tôi sử dụng biệt hiệu làm ví dụ ở đây, bởi vì các câu lạc bộ bóng đá Mỹ thường có nhiều hơn một biệt hiệu, ví dụ:Câu lạc bộ bóng đá Chicago Fire có các biệt danh:'The Fire', 'La Máquina Roja', 'Men in Red', 'CF97', v.v.)

KHÔNG PHẢI TRẢ LỜI CHO CÂU HỎI CỦA BẠN NHƯNG ...

Tôi đã đề cập nhiều lần trước đây, rằng tôi không thích làm việc với triển khai cơ sở dữ liệu EAV đến mức nào? IMO nên là một truy vấn rất đơn giản, biến thành một con thú quá phức tạp của một truy vấn có khả năng làm mờ ánh sáng.

Sẽ không đơn giản hơn nhiều khi tạo một bảng trong đó mỗi "thuộc tính" là một cột riêng biệt phải không? Sau đó, các truy vấn để trả về các tập kết quả hợp lý sẽ trông hợp lý hơn ...

SELECT id, name, nickname, city, captain, f_number, ... FROM team

Nhưng điều thực sự khiến tôi rùng mình là viễn cảnh một nhà phát triển nào đó sẽ quyết định rằng LDQ nên được "ẩn" trong cơ sở dữ liệu dưới dạng một chế độ xem, để kích hoạt truy vấn "đơn giản hơn".

Nếu bạn đi theo con đường này, VUI LÒNG XIN VUI LÒNG chống lại bất kỳ sự thúc giục nào bạn có thể phải lưu trữ truy vấn này trong cơ sở dữ liệu dưới dạng một dạng xem.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Mệnh đề INNER JOIN ON so với WHERE

  2. Xác định khóa tổng hợp với tính năng tăng tự động trong MySQL

  3. Làm cách nào để thoát đầu vào db MySQL trong Python3?

  4. Quyền truy cập bị từ chối đối với người dùng '' @ 'localhost' (sử dụng mật khẩu:KHÔNG)

  5. Làm thế nào để có được một kết xuất chính xác bằng cách sử dụng mysqldump và một giao dịch khi DDL được sử dụng cùng một lúc?