SQL Query,FULL JOIN,性能

时间:2011-07-08 07:53:34

标签: sql sql-server performance

我有一个包含一个人属性的表,同一个人最多可以拥有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

有关如何更有效地进行此查询的任何建议吗?

4 个答案:

答案 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)

这可以通过PIVOTUNPIVOT操作的组合来完成。

;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