sql - 没有聚合函数的动态 TSQL Pivot
问题描述
我有一张这样的表('ExternalPersonRelationTable')
个人身份 | 主题代码 |
---|---|
4187 | 3 |
4187 | 278 |
4429 | 3 |
4429 | 4 |
4463 | 99 |
4464 | 174 |
4464 | 175 |
我想轮换数据,以便表中的每个人都获得一个列和每个主题代码的 TRUE/FALSE 值,即这样的表:
代码 | 4187 | 4429 | 4463 | 4464 |
---|---|---|---|---|
3 | 真的 | 真的 | 错误的 | 错误的 |
4 | 错误的 | 真的 | 错误的 | 错误的 |
... | ||||
99 | 错误的 | 错误的 | 真的 | 错误的 |
... | ||||
174 | 错误的 | 错误的 | 错误的 | 真的 |
175 | 错误的 | 错误的 | 错误的 | 真的 |
我认为这是我应该使用 PIVOT 和动态 SQL 解决的问题,但恐怕我的经验仅限于使用 CTE 和简单的 JOIN,所以我很难 PIVOTing 数据,更不用说动态命名结果列。
SubjectCode 和 PersonId 最终将连接到其他表以获取它们的真实值,但对于示例,我认为它们是不必要的。
我该如何解决这个问题?
解决方案
样本数据
create table ExternalPersonRelationTable
(
PersonId int,
SubjectCode int
);
insert into ExternalPersonRelationTable (PersonId, SubjectCode) values
(4187, 3),
(4187, 278),
(4429, 3),
(4429, 4),
(4463, 99),
(4464, 174),
(4464, 175);
解决方案
从枢轴查询的(有限)静态版本作为参考开始。
select piv.SubjectCode as Code,
isnull(convert(bit, piv.[4187]), 0) as [4187],
isnull(convert(bit, piv.[4429]), 0) as [4429],
isnull(convert(bit, piv.[4463]), 0) as [4463],
isnull(convert(bit, piv.[4464]), 0) as [4464]
from ExternalPersonRelationTable epr
pivot (max(epr.PersonId) for epr.PersonId in ([4187],[4429],[4463],[4464])) piv;
识别动态部分并构建(并验证)它们。
-- constuct lists
declare @fieldList nvarchar(1000);
declare @pivotList nvarchar(1000);
with cte as
(
select epr.PersonId
from ExternalPersonRelationTable epr
group by epr.PersonId
)
select @fieldList = string_agg('isnull(convert(bit, piv.['
+ convert(nvarchar(10), cte.PersonId)
+ ']), 0) as ['
+ convert(nvarchar(10), cte.PersonId)
+ ']', ', ') within group (order by cte.PersonId),
@pivotList = string_agg('['
+ convert(nvarchar(10), cte.PersonId)
+ ']', ',') within group (order by cte.PersonId)
from cte;
-- validate lists
select @fieldList as FieldList;
select @pivotList as PivotList;
在最终查询中合并动态部分(并在开发阶段进行验证)。
-- construct query
declare @query nvarchar(3000) = 'select piv.SubjectCode as Code, '
+ @fieldList
+ 'from ExternalPersonRelationTable epr '
+ 'pivot (max(epr.PersonId) for epr.PersonId in ('
+ @pivotList
+ ')) piv;';
-- validate query
select @query as Query;
运行动态查询。
-- run query
exec sp_executesql @query;
结果
Code 4187 4429 4463 4464
---- ----- ----- ----- -----
3 True True False False
4 False True False False
99 False False True False
174 False False False True
175 False False False True
278 True False False False
小提琴以查看实际情况。
推荐阅读
- java - Firebase 聊天应用接收通知
- python - 如何从 C 函数签名中确定 Python3 ctypes .argtypes?
- java - 如何从 Maven 输出中删除 [INFO] 和 [ERROR] 标签?
- reactjs - 使用材质 ui TextField 显示 imask 的问题
- python - 如何在 AWS EC2 上运行 python 代码然后使用 POST?
- vhdl - 在 VHDL 中初始化矩阵需要大量类型的逻辑单元块
- elasticsearch - Elasticsearch 搜索时间分析器非常慢
- node.js - 收集计数不正确(MongoDB)
- sql - 我有一个与 Invoice 表有 1-N 关系的表 Claims,我需要在 SQL 中找到其发票具有特定价值的所有索赔
- amazon-cognito - 通过电子邮件而不是 SMS 发送 OTP -Cognito