我正在使用查询
(select top (1) a.Description from ClientContactAttributes cca inner join Attributes a on a.AttributeId = cca.AttributeId where cca.ClientContactId = cc.ClientContactId order by cca.AttributeId desc) as Attribute1,
(select top (1) Description from (select top (2) a.Description, cca.AttributeId from ClientContactAttributes cca inner join Attributes a on a.AttributeId = cca.AttributeId where cca.ClientContactId = cc.ClientContactId order by cca.AttributeId desc) q order by q.AttributeId asc) as Attribute2,
(select top (1) Description from (select top (3) a.Description, cca.AttributeId from ClientContactAttributes cca inner join Attributes a on a.AttributeId = cca.AttributeId where cca.ClientContactId = cc.ClientContactId order by cca.AttributeId desc) q order by q.AttributeId asc) as Attribute3,
etc
获取针对记录添加的属性列表。目前,如果任何属性已添加到该记录,它会多次返回最终结果,但理想情况下,如果该属性不存在,我希望返回NULL。
而不是返回
Attribute1 Attribute2 Attribute3 Attribute4
Bed Bath Beyond Beyond
Bed Bed Bed Bed
我宁愿回来
Attribute1 Attribute2 Attribute3 Attribute4
Bed Bath Beyond NULL
Bed NULL NULL NULL
这样做的最佳方式是什么?
答案 0 :(得分:1)
使用ROW_NUMBER()
。首先为每个记录分配一个行号:
SELECT cca.ClientContactId,
a.Description,
RowNumber = ROW_NUMBER() OVER(PARTITION BY cca.ClientContactId
ORDER BY a.AttributeId)
FROM ClientContactAttributes AS cca
INNER JOIN Attributes AS a
ON a.AttributeId = cca.AttributeId;
然后,您可以使用此RowNumber
列来PIVOT
您的数据:
WITH Data AS
( SELECT cca.ClientContactId,
a.Description,
RowNumber = ROW_NUMBER() OVER(PARTITION BY cca.ClientContactId
ORDER BY a.AttributeId)
FROM ClientContactAttributes AS cca
INNER JOIN Attributes AS a
ON a.AttributeId = cca.AttributeId
)
SELECT pvt.ClientContactID,
Attribute1 = pvt.[1],
Attribute2 = pvt.[2],
Attribute3 = pvt.[3],
Attribute4 = pvt.[4]
FROM Data
PIVOT
( MAX(Description)
FOR RowNumber IN ([1], [2], [3], [4])
) AS pvt;
修改强>
如果你不明白,那么我没有正确回答!我坚信谚语"给一个人一条鱼,你喂他一天;教一个人钓鱼,你喂他一辈子"
如果您的两个表格中包含以下数据:
<强>属性强>&#39;
AttributeId | Description
------------+---------------
1 | Bed
2 | Bath
3 | Beyond
<强> ClientContactAttributes 强>
ClientContactID | AttributeId
----------------+---------------
1 | 1
1 | 2
1 | 3
2 | 1
运行以下内容:
SELECT cca.ClientContactId,
a.Description,
RowNumber = ROW_NUMBER() OVER(PARTITION BY cca.ClientContactId
ORDER BY a.AttributeId)
FROM ClientContactAttributes AS cca
INNER JOIN Attributes AS a
ON a.AttributeId = cca.AttributeId;
会给你:
ClientContactID | Description | RowNumber
----------------+-------------+-----------
1 | Bed | 1
1 | Bath | 2
1 | Beyond | 3
2 | Bed | 1
ROW_NUMBER()
函数只为每个组分配一个唯一的编号(在PARTITION BY
子句中定义),该编号由ORDER BY
子句确定。所以这一行:
ROW_NUMBER() OVER(PARTITION BY cca.ClientContactId ORDER BY a.AttributeId)
基本上是说,对于cca.ClientContactId
的每个唯一值,我想要一个唯一的数字,从1开始,attributeId
的最低值收到1,数字从那里开始递增:
PIVOT函数非常类似于excel数据透视表,您希望将行转换为列。它有两个基本部分,我将在这里工作。第一部分是FOR
子句:
FOR RowNumber IN ([1], [2], [3], [4])
这是您要转换为行的RowNumber
列中的值。列名将对应于提供的值。第二部分(第一个逻辑读取)定义将进入这些新创建的列的值。这必须是一个聚合函数,在这种情况下它是:
MAX(Description)
由于您已经知道RowNumber
对于每个ClientContactId
都是唯一的,因此聚合函数(PIVOT`所需的)实际上没有意义,因为只有一个值可用于聚合。< / p>
希望这更有意义。