Search code examples
sqldatabaseattributessql-server-expressentity-attribute-value

SQL SELECT from and EAV table


Based on my previous questions I have this following tables:

  IrisColor 
  ID Description
   1 Blue 
   2 Gray 
   3 Green 
   4 Brown

 SkinColor 
  ID Description
   1 White 
   2 Asian 
   3 Dark       

Gender
  ID Description
   1 Male 
   2 Female 

And the Attributes table

Attributes
  ID Description
   1 SkinColor 
   2 IrisColor 
   3 Gender

And also the EAV table:

PersonDetails
  PersonID AttributeID ValueID
   121       1            1
   121       2            2
   121       3            1
   122       1            2
   122       2            1
   122       3            1

So if I would want to select the Name, the attribute name and value for only the SkinColor I would do something like this:

SELECT p.Name,
       a.Description,
       v.Description
       FROM PersonDetails AS sd 
       INNER JOIN Subjects AS p ON sd.PersonID=p.ID 
       INNER JOIN SubjectAttributes AS a ON sd.AttributeID=a.ID
       INNER JOIN SkinColor AS v ON sd.ValueID= v.ID

But what should I do If I would want to select all the information for all of the persons from the database, not only skin color but iris color and gender too?

Previously I knew that from SkinColor I wanted to select that value, but in the PersonDetails I also have Values for IrisColor and Gender.

INNER JOIN SkinColor AS v ON sd.ValueID= v.ID this won't be appropriate anymore. How to replace this with something more dynamical?

Update:

I used this statement:

SELECT
    SubjectID,
    SkinColor,
    IrisColor,
    EyeLidFlisure,
    KnownEyeDeffect,
    Ethnicity,
    Height,
    DrivingLicense,
    Gender
FROM
(
SELECT SubjectID, attr.Description as attribute, ValueID from SubjectDetails, SubjectAttributes as attr WHERE SubjectDetails.AttributeID=attr.ID
) as t
PIVOT(MAX(ValueID) FOR attribute IN (SkinColor,IrisColor,Gender,EyeLidFlisure,KnownEyeDeffect,Ethnicity,Height,DrivingLicense)) AS t1

Now, I have all the attributes listed in separate columns, but instead of Value description I have Value ID. How should I continue?


Solution

  • This would be the complete solution (don't know if it is the easiest one.. but it works)

    WITH Subject AS (
    
    SELECT
        SubjectID,
        SkinColor,
        IrisColor,
        EyeLidFlisure,
        KnownEyeDeffect,
        Ethnicity,
        Height,
        DrivingLicense,
        Gender
    FROM
    (
    SELECT SubjectID, attr.Description as attribute, ValueID from SubjectDetails, SubjectAttributes as attr WHERE SubjectDetails.AttributeID=attr.ID
    ) as t
    PIVOT(MAX(ValueID) FOR attribute IN (SkinColor,IrisColor,Gender,EyeLidFlisure,KnownEyeDeffect,Ethnicity,Height,DrivingLicense)) AS t1
    )
    
    SELECT SubjectID,
    whole.Name as Name,
    whole.eMail as eMail,
    skincolor.Description as SkinColor, 
    iriscolor.Description as IrisColor,
    eyelid.Description as EyeLidFlisure,
    defect.Description as KnownEyeDeffect,
    eth.Description as Ethnicity,
    height.Description as Height,
    dl.Description as DrivingLicense,
    gender.Description as Gender
    
    FROM Subject S
    Left JOIN Subjects whole ON whole.ID=S.SubjectID
    Left JOIN SkinColor skincolor ON S.SkinColor=skincolor.ID
    Left JOIN IrisColor iriscolor ON S.IrisColor=iriscolor.ID
    Left JOIN EyeLidFlisure eyelid ON S.EyeLidFlisure=eyelid.ID
    Left JOIN KnownEyeDeffect defect ON S.KnownEyeDeffect=defect.ID
    Left JOIN Ethnicity eth ON S.Ethnicity=eth.ID
    Left JOIN Height height ON S.Height=height.ID
    Left JOIN DrivingLicense dl ON S.DrivingLicense=dl.ID
    Left JOIN Gender gender ON S.Gender=gender.ID