sql >> Database teknologi >  >> RDS >> Mysql

SQL-problem:et til mange forhold og EAV-model

Det korte svar på dit spørgsmål er nej, der er ingen enkel konstruktion i MySQL til at opnå det resultatsæt, du leder efter.

Men det er muligt omhyggeligt (omhyggeligt) at lave en sådan forespørgsel. Her er et eksempel, jeg stoler på, at du vil være i stand til at tyde det. Grundlæggende bruger jeg korrelerede underforespørgsler i udvalgslisten for hver egenskab, jeg vil have returneret.

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

For "multi-valued" attributter skal du trække hver forekomst af attributten separat. (Brug LIMIT til at angive, om du henter den første, den anden osv.)

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

Jeg bruger kaldenavn som eksempel her, fordi amerikanske fodboldklubber ofte har mere end ét kaldenavn, f.eks. Chicago Fire Soccer Club har kaldenavne:'The Fire', 'La Máquina Roja', 'Men in Red', 'CF97', et al.)

IKKE ET SVAR PÅ DIT SPØRGSMÅL, MEN ...

Har jeg nævnt adskillige gange før, hvor meget jeg ikke kan lide at arbejde med EAV-databaseimplementeringer? Hvad skal IMO være en meget simpel forespørgsel, bliver til et alt for kompliceret bæst af en potentielt let dæmpningsforespørgsel.

Ville det ikke være meget nemmere at lave en tabel, hvor hver "attribut" er en separat kolonne? Så ville forespørgsler om at returnere rimelige resultatsæt se mere fornuftige ud...

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

Men det, der virkelig får mig til at gyse, er udsigten til, at en eller anden udvikler vil beslutte, at LDQ'en skal "skjules" i databasen som en visning for at aktivere den "enkle" forespørgsel.

Hvis du går denne vej, VENLIGST VENLIGST VENLIGST modstå enhver trang, du måtte have til at gemme denne forespørgsel i databasen som en visning.



  1. hvordan finder og erstatter man et ord i en mysql-kolonne?

  2. Mysql_install_db kan ikke finde filen

  3. Sådan omdøbes en SQL Server-database ved hjælp af T-SQL

  4. MySQL bruger ikke indekser med WHERE IN-klausulen?