Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Problem z SQL:relacja jeden do wielu i model EAV

Krótka odpowiedź na twoje pytanie brzmi:nie, w MySQL nie ma prostej konstrukcji, która pozwoliłaby uzyskać zestaw wyników, którego szukasz.

Ale możliwe jest ostrożne (z mozołem) spreparowanie takiego zapytania. Oto przykład, ufam, że będziesz w stanie go rozszyfrować. Zasadniczo używam skorelowanych podzapytań na liście wyboru, dla każdego atrybutu, który chcę zwrócić.

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

W przypadku atrybutów „wielowartościowych” musisz pobrać osobno każde wystąpienie atrybutu. (Użyj LIMIT, aby określić, czy pobierasz pierwszy, drugi itd.)

     , ( 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

Podaję tutaj pseudonim jako przykład, ponieważ amerykańskie kluby piłkarskie często mają więcej niż jeden pseudonim, np. Chicago Fire Soccer Club ma pseudonimy:„Ogień”, „La Máquina Roja”, „Mężczyźni w czerwieni”, „CF97” i inni)

NIE ODPOWIEDŹ NA TWOJE PYTANIE, ALE...

Czy wspominałem już wielokrotnie, jak bardzo nie lubię pracować z implementacjami baz danych EAV? To, co IMO powinno być bardzo prostym zapytaniem, zamienia się w nadmiernie skomplikowaną bestię potencjalnie przyciemniającą zapytanie.

Czy nie byłoby o wiele prościej utworzyć tabelę, w której każdy „atrybut” jest osobną kolumną? Wtedy zapytania zwracające rozsądne zestawy wyników wyglądałyby bardziej rozsądnie...

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

Ale to, co naprawdę mnie przeraża, to perspektywa, że ​​jakiś programista zdecyduje, że LDQ powinno być „ukryte” w bazie danych jako widok, aby umożliwić „prostsze” zapytanie.

Jeśli pójdziesz tą drogą, PROSZĘ PROSZĘ oprzeć się pokusie zapisania tego zapytania w bazie danych jako widoku.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Czy można wywołać procedurę składowaną w widoku?

  2. mysql przekazuje dane do in

  3. Jak uniknąć sytuacji wyścigowej dzięki unikalnym kontrolom w Django

  4. Jak możemy wysłać dane w MySQL, gdy formularz ma ustawioną wartość enctype=multipart/form-data w node.js?

  5. Procedury składowane MySql:Jak wybrać z tabeli procedur?