Mysql
 sql >> база данни >  >> RDS >> Mysql

Проблем със SQL:връзка едно към много и модел на EAV

Краткият отговор на вашия въпрос е не, няма проста конструкция в MySQL за постигане на набора от резултати, който търсите.

Но е възможно внимателно (старателно) да изработите такава заявка. Ето един пример, вярвам, че ще можете да го дешифрирате. По принцип използвам корелирани подзаявки в списъка за избор за всеки атрибут, който искам да бъде върнат.

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

За атрибути с много стойности ще трябва да изтеглите всеки екземпляр на атрибута поотделно. (Използвайте LIMIT, за да посочите дали извличате първия, втория и т.н.)

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

Тук използвам псевдоним като пример, защото американските футболни клубове често имат повече от един прякор, напр. Футболният клуб Chicago Fire има прякори:„Огънят“, „La Máquina Roja“, „Мъже в червено“, „CF97“ и др.)

НЕ ОТГОВОР НА ВАШИЯ ВЪПРОС, НО ...

Споменвал ли съм много пъти преди колко не харесвам да работя с реализации на база данни на EAV? Това, което IMO трябва да бъде много проста заявка, се превръща в твърде сложна заявка за потенциално леко затъмняване.

Не би ли било много по-лесно да създадете таблица, където всеки "атрибут" е отделна колона? Тогава заявките за връщане на разумни набори от резултати биха изглеждали по-разумни...

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

Но това, което наистина ме кара да потръпвам, е перспективата, че някой разработчик ще реши, че LDQ трябва да бъде „скрит“ в базата данни като изглед, за да активира „по-простата“ заявка.

Ако тръгнете по този път, МОЛЯ, МОЛЯ, МОЛЯ, откажете се от всяко желание, което може да се наложи да съхраните тази заявка в базата данни като изглед.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. symfony2 динамична връзка с база данни с помощта на doctrine

  2. ГРЕШКА:Допълнителна информация:Външната таблица не е в очаквания формат

  3. MySQL конзолата е бавна при импортиране на огромни SQL файлове

  4. Как да съхранявате данните в unicode на хинди език

  5. Как да съхранявате Java Date в Mysql datetime с JPA