sql >> Databáze >  >> RDS >> Mysql

Problém SQL:jeden k mnoha vztah a model EAV

Krátká odpověď na vaši otázku je ne, v MySQL neexistuje žádná jednoduchá konstrukce, která by vám umožnila dosáhnout sady výsledků, kterou hledáte.

Ale je možné pečlivě (pracně) vytvořit takový dotaz. Zde je příklad, věřím, že ho dokážete rozluštit. V zásadě používám korelované poddotazy ve výběrovém seznamu pro každý atribut, který chci vrátit.

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

U atributů s více hodnotami byste museli vytáhnout každou instanci atributu samostatně. (Použijte LIMIT k určení, zda načítáte první, druhý atd.)

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

Zde uvádím jako příklad přezdívku, protože americké fotbalové kluby mají často více přezdívek, např. Chicago Fire Soccer Club má přezdívky:'The Fire', 'La Máquina Roja', 'Men in Red', 'CF97' a další)

NENÍ ODPOVĚĎ NA VAŠI OTÁZKU, ALE ...

Už jsem mnohokrát zmínil, jak moc nerad pracuji s implementacemi databáze EAV? To, co by IMO měl být velmi jednoduchý dotaz, se změní v příliš komplikovanou bestii s potenciálně lehkým stmíváním.

Nebylo by mnohem jednodušší vytvořit tabulku, kde je každý „atribut“ samostatný sloupec? Pak by dotazy, které mají vrátit rozumné sady výsledků, vypadaly rozumněji...

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

Ale co mě opravdu rozechvěje, je vyhlídka, že se nějaký vývojář rozhodne, že LDQ by mělo být „skryto“ v databázi jako pohled, aby se umožnil „jednodušší“ dotaz.

Pokud se vydáte touto cestou, PROSÍM, PROSÍM, odolejte jakékoli potřebě uložit tento dotaz do databáze jako pohled.



  1. Jak definovat sloupec, který dokáže automatizovat psaní velkých písmen?

  2. Změna sloupce:null na ne null

  3. Nahrajte více obrázků a uložte jejich cestu do databáze

  4. Friendship System Sql Structure &Query