SQL SELECT 来自和 EAV table
SQL SELECT from and EAV table
根据我之前的问题,我有以下 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
和属性 table
Attributes
ID Description
1 SkinColor
2 IrisColor
3 Gender
还有 EAV table:
PersonDetails
PersonID AttributeID ValueID
121 1 1
121 2 2
121 3 1
122 1 2
122 2 1
122 3 1
因此,如果我只想 select 名称、属性名称和 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
但是如果我想 select 数据库中所有人的所有信息,不仅是肤色,还有虹膜颜色和性别,我该怎么办?
以前我知道我想从 SkinColor select 该值,但在 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。我该如何继续?
您的数据模型有点神秘,因为您在 "person details" table 中的 ID 不能具有适当的外键关系。您可以 将所有属性放在同一个table 中。或者每个属性都有一个单独的 table。或者——与 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';
我猜你需要动态 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);
这将是完整的解决方案(不知道它是否是最简单的..但它有效)
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
根据我之前的问题,我有以下 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
和属性 table
Attributes
ID Description
1 SkinColor
2 IrisColor
3 Gender
还有 EAV table:
PersonDetails
PersonID AttributeID ValueID
121 1 1
121 2 2
121 3 1
122 1 2
122 2 1
122 3 1
因此,如果我只想 select 名称、属性名称和 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
但是如果我想 select 数据库中所有人的所有信息,不仅是肤色,还有虹膜颜色和性别,我该怎么办?
以前我知道我想从 SkinColor select 该值,但在 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。我该如何继续?
您的数据模型有点神秘,因为您在 "person details" table 中的 ID 不能具有适当的外键关系。您可以 将所有属性放在同一个table 中。或者每个属性都有一个单独的 table。或者——与 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';
我猜你需要动态 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);
这将是完整的解决方案(不知道它是否是最简单的..但它有效)
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