sql - 数据的组合半转置
问题描述
考虑以下查询:
DECLARE @T1 TABLE(
[Id] [int] IDENTITY(1,1) NOT NULL,
[Data] VARCHAR(100),
[Column1] VARCHAR(100),
[Column2] VARCHAR(100),
[Column3] VARCHAR(100));
INSERT INTO @T1([Data],[Column1],[Column2],[Column3])
VALUES
('Data1','C11','C21','C31'),
('Data2','C12','C22','C32'),
('Data3','C13','C23','C33'),
('Data4','C14','C24','C34'),
('Data5','C15','C25','C35');
SELECT * FROM @T1;
输出如下所示:
现在我们要保留 Data 列,并为每个其他列堆叠选择该列的结果到最终表中。换句话说,以下查询产生输出:
-- I am looking for a better solution than below!
DECLARE @output TABLE([Data] VARCHAR(100),[Column] VARCHAR(100));
INSERT INTO @output([Data],[Column])
(SELECT [Data],[Column1] FROM @T1
UNION
SELECT [Data],[Column2] FROM @T1
UNION
SELECT [Data],[Column3] FROM @T1)
SELECT * FROM @output
有什么比上面更清洁的方法来产生最终输出?随着列数的增加,这意味着对于每一个新列,我都需要一个单独的插入,这似乎是一个粗略的解决方案。理想情况下,我正在寻找基于枢轴的解决方案,但我无法提出具体的建议。
解决方案
当然,Yogesh 的解决方案会更高效。但是,由于您的列会随着时间的推移而扩展,因此这里有一种方法可以“动态地”在不实际使用 Dynamic SQ 的情况下对您的数据进行反透视:
例子
Select A.[Data]
,C.*
From @T1 A
Cross Apply ( values (cast((Select A.* for XML RAW) as xml))) B(XMLData)
Cross Apply (
Select Item = xAttr.value('local-name(.)', 'varchar(100)')
,Value = xAttr.value('.','varchar(100)')
From XMLData.nodes('//@*') xNode(xAttr)
Where xAttr.value('local-name(.)','varchar(100)') not in ('Id','Data','Other-Columns','To-Exclude')
) C
退货
推荐阅读
- javascript - Kibana 不显示从 Node.js Winston Logger 发送到 Elasticsearch 的日志
- php - 如果我使用 AWS RDS 将用户输入存储到数据库中,我的 PHP 文件应该放在哪里?
- java - 如何跟踪 Java 异常
- python - 在 Tkinter 中,有没有办法在运行程序时停止执行回调函数?
- c++ - 我如何计算向量[5][1] N 次
- json - Ionic - 带有 laravel json 响应的 API
- javascript - 如何使用 JS 控制 CSS 过渡和动画?
- c++ - 如何将按位运算符与 unsigned char 数据类型一起使用?
- python - 替换 np.array 中元素的更快方法
- c - 返回从 volatile 标量初始化的字符串表现得很奇怪?