sql >> Database >  >> RDS >> Mysql

SQL-probleem:een-op-veel-relatie en EAV-model

Het korte antwoord op uw vraag is nee, er is geen eenvoudige constructie in MySQL om de resultatenset te bereiken waarnaar u op zoek bent.

Maar het is mogelijk om zo'n query zorgvuldig (nauwgezet) op te stellen. Hier is een voorbeeld, ik vertrouw erop dat u het kunt ontcijferen. In feite gebruik ik gecorreleerde subquery's in de selectielijst, voor elk attribuut dat ik wil retourneren.

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

Voor kenmerken met meerdere waarden moet u elke instantie van het kenmerk afzonderlijk ophalen. (Gebruik de LIMIT om aan te geven of u de eerste, de tweede, enz. ophaalt.)

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

Ik gebruik hier bijnaam als voorbeeld, omdat Amerikaanse voetbalclubs vaak meer dan één bijnaam hebben, b.v. Chicago Fire Soccer Club heeft bijnamen:'The Fire', 'La Máquina Roja', 'Men in Red', 'CF97', et al.)

GEEN ANTWOORD OP UW VRAAG, MAAR ...

Heb ik al vaker gezegd dat ik een hekel heb aan het werken met EAV-database-implementaties? Wat IMO een heel eenvoudige vraag zou moeten zijn, verandert in een te gecompliceerd beest van een mogelijk licht dimmende vraag.

Zou het niet veel eenvoudiger zijn om een ​​tabel te maken waarin elk "attribuut" een aparte kolom is? Dan zouden query's om redelijke resultatensets te retourneren er redelijker uitzien...

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

Maar wat me echt doet huiveren, is het vooruitzicht dat een ontwikkelaar gaat besluiten dat de LDQ als een weergave in de database moet worden "verborgen" om de "eenvoudigere" zoekopdracht mogelijk te maken.

Als u deze route volgt, PLEASE PLEASE PLEASE PLEASE PLEASE PLEASE PLEASE PLEASE PLEASE PLEASE PLEASE PLEASE PLEASE PLEASE PLEASE PLEASE PLEASE PLEASE PLEASE PLEASE PLEASE PLEASE PLEASE PLEASE PLEASE PLEASE PLEASE PLEASE ANGELES DIE u mogelijk heeft om deze query op te slaan in de database als een weergave.



  1. opencart - Hoe kan ik handmatig een module in een sjabloonbestand weergeven?

  2. Verwarring met Oracle CONNECT BY

  3. gegevens ophalen uit mysql en e-mailen

  4. Een manier om te controleren of Oracle klaar is met sql