1

根據我以前的問題,我有這個下表:SQL SELECT從和EAV表

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 

並且屬性表

Attributes 
    ID Description 
    1 SkinColor 
    2 IrisColor 
    3 Gender 

而且還EAV表:

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

所以如果我想要選擇名稱,只有SkinColor的屬性名稱和值我會做這樣的事情:

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 

但我應該怎麼辦?如果我想從數據庫中,不僅膚色,但虹膜顏色和性別也選擇對所有的人的所有信息?

以前我知道從SkinColor中選擇那個值,但在PersonDetails中我也有IrisColor和Gender的值。

INNER JOIN SkinColor AS v ON sd.ValueID = v.ID這將不再合適。如何用更具動態性的東西來取代它?

更新:

我用這樣的說法:

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 

現在,我已經在單獨的列中列出的所有屬性,但不是價值說明我值ID。我應該如何繼續?

+0

將EAV轉換爲常規表PersonDetailsT(PersonID,SkinColor,IrisColor,性別......)並將其加入適當的表格。數據透視是DBMS特有的,正確標記DBMS。 – Serg

+0

你可以對連接部分更具體一點嗎?因爲這正是我現在的問題。 – berthos

+0

什麼是您的DBMS? – Serg

回答

0

這將是完整的解決方案(不知道它是最簡單的一個..但它的工作原理)

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 
1

您的數據模型有點神祕,因爲您在「人員詳細信息」表中沒有適當的外鍵關係的ID。你可能把所有的屬性放在同一個表中。或者爲每個屬性設置一個單獨的表格。或者 - 與EAV模型一樣 - 將說明直接放入PersonDetails

你將需要做這樣的事情:

SELECT p.Name, 
     sa.Description, 
     ic.Description as IrisColor, 
     g.Description as gender 
FROM PersonDetails sd INNER JOIN 
    Subjects p 
    ON sd.PersonID = p.ID INNER JOIN 
    SubjectAttributes sa 
    ON sd.AttributeID = sa.ID 
    ON LEFT JOIN 
    SkinColor sc 
    ON sd.ValueID = sc.ID AND sa.Description = 'SkinColor' LEFT JOIN 
    IrisColor ic 
    ON sd.ValueId = ic.ID AND sa.Description = 'IrisColor' LEFT JOIN 
    Gender g 
    ON sd.ValueId = g.ID AND sa.Description = 'Gender'; 
1

猜你需要從屬性建立動態SQL字典

declare @sql varchar(max)= 
    'select PersonID , ' + 
    + stuff((select ','+Description + '.Description as ' + Description 
      from Attributes 
     for xml path ('')),1,1,'') 
    + ' from (select PersonID, ' 
    + stuff((select ',max(case AttributeID when ' + cast(ID as varchar(5)) +' then ValueID end) as ' + Description 
     from Attributes 
     for xml path ('')),1,1,'') 
    +' from PersonDetails group by PersonID) pvt' 
    + (select ' left join ' + Description + ' on pvt.' + Description + ' = '+ Description + '.ID' 
     from Attributes 
     for xml path ('')); 

exec (@sql);