根据我以前的问题,我有以下表格:
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 :(得分:1)
您的数据模型有点神秘,因为您的人员详细信息中包含了ids。表没有正确的外键关系。您可以将所有属性放在同一个表中。或者为每个属性都有一个单独的表。或者 - 与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 :(得分: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);
答案 2 :(得分: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