我有一个包含一个人属性的表,同一个人最多可以拥有18个不同的属性。该表如下所示:
Personid, Propertytype, Propertyvalue, Propertyname
我想使用FULL JOIN进行SQL查询,以便将一个人的所有属性放入结果集中的一行。 我已经做了这样的查询,但我认为如果你考虑响应时间/性能,这不是最佳选择。 在数据库中,我有超过1200万人,所以它有很多数据行。
我的SQL查询:
SELECT DISTINCT (Information.PersonID),
f.PersonName,
f1.Property AS 'P1',
f1.PropertyValue AS 'P1Value',
f1.PropertyName AS 'P1Name',
f2.Property AS 'P2',
f2.PropertyValue AS 'P2Value',
f2.PropertyName AS 'P2Name',
......
FROM Person f
FULL JOIN (
SELECT
PersonName,
Property,
PropertyValue,
PropertyName
FROM Person WHERE Property='P1'
GROUP BY PersonName, Property, PropertyValue, PropertyName
) f1 ON f.PersonName=f1.PersonName
FULL JOIN (
SELECT PersonName,
Property,
PropertyValue,
PropertyName
FROM Person WHERE Property='P2'
GROUP BY PersonName, Property, PropertyValue, PropertyName
) f2 ON f.PersonName=f2.PersonName
....
INNER JOIN Information ON f.PersonName = Information.Name
有关如何更有效地进行此查询的任何建议吗?
答案 0 :(得分:2)
您可以选择所需的行,然后将行PIVOT到列中,1种方法是在每个id的select中使用case语句。 这将减少针对人员表的扫描次数。(因为您只扫描一次表) e.g:
SELECT personID,PersonName, max(p1val),max(p1name),max(p2val),max(p2name) ...etc
FROM
(
SELECT Information.PersonID,
f.PersonName,
case WHEN Property ='P1' THEN PropertyValue ELSE NULL END as p1val,
case WHEN Property ='P2' THEN PropertyValue ELSE NULL END as p2val,
case WHEN Property ='P3' THEN PropertyValue ELSE NULL END as p3val,
....etc
case WHEN Property ='P1' THEN PropertyName ELSE NULL END as p1name,
case WHEN Property ='P2' THEN PropertyName ELSE NULL END as p2name,
case WHEN Property ='P3' THEN PropertyName ELSE NULL END as p3name,
.....etc
FROM Person f
)
GROUP BY personID,PersonName
答案 1 :(得分:2)
尝试使用PIVOT。这里链接到BOL ...... http://link.phillip.pe/SQLPivot。
它将单个列中的多行转换为单行中的多个列,例如
Person1, Left-Handed
Person1, Blue Eyes
Person2, Right-Handed
Person2, Brown Eyes
PIVOT:
Person1, Left-Handed, Blue Eyes
Person2, Right-Handed, Brown Eyes
答案 2 :(得分:1)
我会尝试使用PIVOT
或者这个:
SELECT
i.PersonID
, i.PersonName
, f1.Property AS 'P1'
, f1.PropertyValue AS 'P1Value'
, f1.PropertyName AS 'P1Name'
, f2.Property AS 'P2'
, f2.PropertyValue AS 'P2Value'
, f2.PropertyName AS 'P2Name'
......
FROM
Information AS i
LEFT JOIN Person AS f1
ON f1.PersonID = i.PersonId
AND f1.Property = 'P1'
LEFT JOIN Person AS f2
ON f2.PersonID = i.PersonId
AND f2.Property = 'P2'
......
答案 3 :(得分:0)
这可以通过PIVOT
和UNPIVOT
操作的组合来完成。
;WITH a AS
(
SELECT PersonName
, Property [Prefix]
, Property [ ]
, PropertyValue [Value]
, PropertyName [Name]
FROM dbo.Person
)
, c AS
(
SELECT b.PersonName, RTRIM(b.Prefix + b.Suffix) Field, b.Data
FROM a
UNPIVOT (Data FOR Suffix IN ([ ], [Value], [Name])) b
)
SELECT d.*
FROM c PIVOT (MIN(Data) FOR Field IN
(
[P1], [P1Value], [P1Name]
, [P2], [P2Value], [P2Name]
, [P3], [P3Value], [P3Name]
)) d