一尘不染

如何使用 PIVOT 将值分成不同的列而不重复或 NULL 值

sql

我目前有以下三个表:

Table#Name

Name_id     NameValue
==========  =============
50          Hannah
51          Jeremy
52          Luna 

Table#AttValue

Name_id  AttributeValue_id  AttributeValue
=======  =================  =============
50       11                 01216892584
50       12                 26
50       13                 Female

#属性

AttributeValue_id  AttributeName
=================  =============
11                 Phone Number
12                 Age
13                 Gender

我想要做的是将它们合二为一,这就是我到目前为止所做的:

SELECT NameValue,
case when AttributeName = 'Phone Number' then AttributeValue end PhoneNumber
,case when AttributeName = 'Age' then AttributeValue end Age
,case when AttributeName = 'Gender' then AttributeValue end Gender
FROM #Name A
INNER JOIN #AttValue B ON A.Name_id = B.Name_id
INNER JOIN #Attribute C ON B.AttributeValue_id = C.AttributeValue_id

这很好用,但是它会导致我希望避免的多个 NameValues 和 NULL 值:

NameValue  PhoneNumber  Age  Gender
=========  ============  ===  ======
Hannah     01216892584   NULL NULL
Hannah     NULL          26   NULL
Hannah     NULL          NULL Female

我正在寻找的结果是:

NameValue  PhoneNumber  Age  Gender
=========  ===========  ===  ======
Hannah     01216892584  26   Female

阅读 93

收藏
2022-07-21

共1个答案

一尘不染

假设Name_id, AttributeValue_id是一个键(例如,你没有一个人可能有两个值的PhoneNumber情况 - 或者这些情况存在但你不关心你得到哪一个),最简单的方法是CASE用条件聚合包装你的表达式:

SELECT 
  N.NameValue,
  PhoneNumber = MAX(case when A.AttributeName = 'Phone Number' 
                THEN AV.AttributeValue end),
  Age         = MAX(case when A.AttributeName = 'Age' 
                THEN AV.AttributeValue end),
  Gender      = MAX(case when A.AttributeName = 'Gender' 
                THEN AV.AttributeValue end)
FROM #Name AS N
INNER JOIN #AttValue AS AV ON N.Name_id = AV.Name_id
INNER JOIN #Attribute AS A ON AV.AttributeValue_id = A.AttributeValue_id
GROUP BY N.NameValue;

或枢轴:

;WITH src AS
(
  SELECT N.NameValue, A.AttributeName, AV.AttributeValue
    FROM #Name AS N
    INNER JOIN #AttValue AS AV ON N.Name_id = AV.Name_id
    INNER JOIN #Attribute AS A ON AV.AttributeValue_id = A.AttributeValue_id
)
SELECT 
  p.NameValue, 
  PhoneNumber = p.[Phone Number],
  p.Age, 
  p.Gender
FROM src PIVOT (MAX(AttributeValue)
  FOR AttributeName IN ([Phone Number], [Age], [Gender])) AS p;
2022-07-21