Mysql
 sql >> Datenbank >  >> RDS >> Mysql

SQL-Problem:Eins-zu-viele-Beziehung und EAV-Modell

Die kurze Antwort auf Ihre Frage lautet:Nein, es gibt kein einfaches Konstrukt in MySQL, um die gewünschte Ergebnismenge zu erzielen.

Aber es ist möglich, eine solche Abfrage sorgfältig (mühsam) zu erstellen. Hier ist ein Beispiel, ich vertraue darauf, dass Sie es entziffern können. Grundsätzlich verwende ich korrelierte Unterabfragen in der Auswahlliste für jedes Attribut, das ich zurückgeben möchte.

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

Bei „mehrwertigen“ Attributen müssten Sie jede Instanz des Attributs separat abrufen. (Verwenden Sie das LIMIT, um anzugeben, ob Sie das erste, das zweite usw. abrufen.)

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

Ich verwende hier Spitznamen als Beispiel, da amerikanische Fußballvereine häufig mehr als einen Spitznamen haben, z. Der Chicago Fire Soccer Club hat Spitznamen:„The Fire“, „La Máquina Roja“, „Men in Red“, „CF97“ usw.)

KEINE ANTWORT AUF IHRE FRAGE, ABER ...

Habe ich schon mehrfach erwähnt, wie ungern ich mit EAV-Datenbankimplementierungen arbeite? Was meiner Meinung nach eine sehr einfache Abfrage sein sollte, wird zu einem übermäßig komplizierten Biest einer möglicherweise leicht dimmenden Abfrage.

Wäre es nicht viel einfacher, eine Tabelle zu erstellen, in der jedes "Attribut" eine separate Spalte ist? Dann würden Abfragen zur Rückgabe vernünftiger Ergebnismengen vernünftiger aussehen...

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

Aber was mich wirklich schaudern lässt, ist die Aussicht, dass irgendein Entwickler entscheiden wird, dass die LDQ in der Datenbank als Ansicht "versteckt" werden soll, um die "einfachere" Abfrage zu ermöglichen.

Wenn Sie diesen Weg gehen, widerstehen Sie BITTE BITTE jedem Drang, diese Abfrage als Ansicht in der Datenbank zu speichern.