sql - 带有基于文本的字段的 SQL 透视
问题描述
原谅我,但我不能让这个工作。我可以找到许多使用数值的复杂枢轴,但没有任何基本的基于字符串的基础。
假设这是我来自临时表的源查询。我无法改变这一点:
select * from @tmpTable
这提供了 12 行:
Row | Name | Code
---------------------------------
1 | July 2019 | 19/20-01
2 | August 2019 | 19/20-02
3 | September 2019 | 19/20-03
.. .. ..
12 | June 2020 | 19/20-12
我想对此进行旋转并返回如下数据:
Data Type | [0] | [1] | [3] | [12]
---------------------------------------------------------------------------
Name | July 2019 | August 2019 | September 2019 | June 2020
Code | 19/20-01 | 19/20-02 | 19/20-03 | 19/20-12
提前致谢..
解决方案
字符串和数字在数据透视方面没有太大区别,只是您不能在它们上使用像 SUM 或 AVG 这样的数字聚合器。MAX 会很好,在这种情况下,您将只有一个值,因此不会丢失任何内容
您需要先将数据拉出到更高的键/值表示形式,然后再将其转回以像现在一样反向查看
反透视数据:
WITH upiv AS(
SELECT 'Name' as t, row as r, name as v FROM @tempTable
UNION ALL
SELECT 'Code' as t, row, code FROM @tempTable
)
现在可以在 r 列上重新分组和有条件地聚合数据:
SELECT
t,
MAX(CASE WHEN r = 1 THEN v END) as r1,
MAX(CASE WHEN r = 2 THEN v END) as r2,
...
MAX(CASE WHEN r = 12 THEN v END) as r12
FROM
upiv
GROUP BY
t
您需要将我在这里介绍的两个 sql 块放在一起,以便它们形成一个 sql 语句。如果您想了解更多关于它是如何工作的,我建议您在 with 块中运行 sql 语句,查看它,并从完整语句中删除 group by/max 单词并查看结果。您将看到 WITH 块查询使数据更高,本质上是一个跟踪数据类型(名称或代码)的键/值对。当您在没有 group by/max 的情况下运行完整的 sql 时,您会看到 tall 数据横向展开以提供大量空值和一组对角单元格数据(如果按 r 排序)。group by 折叠所有这些空值,因为 MAX 将选择任何值而不是空值(其中只有一个)
您也可以将其作为 UNPIVOT 后跟 PIVOT。我一直更喜欢使用这种形式,因为不是每个数据库都支持 UN/PIVOT 关键字。可以说,UNPIVOT/PIVOT 可以表现得更好,因为开发人员可以进行特定的优化(例如,UNPIVOT 可以单次扫描表;这种多重联合方法可能需要多次扫描,并且循环它的方式可能会占用更多内存),但在这种情况下,它是只有 12 行。我怀疑您使用的是 SQLServer,但如果您使用的是不理解 WITH 的数据库,您可以将 WITH(包括括号)的括号语句放在 theFROM
和 the之间upiv
,使其成为子查询(如果模式SELECT ... FROM (SELECT ... UNION ALL SELECT ...) upiv GROUP BY ...
; 没有区别
我会将重命名输出列作为练习留给您,但我会敦促您考虑不要在问题中显示的列名中添加空格或方括号
推荐阅读
- ejs - 导航到 ejs 中的公用文件夹
- excel - 如何在 TODAY()+2 打开工作表?
- html - 无法在 CSS 网格中创建一列
- asp.net-mvc - 我需要在 asp.net core 2 REST API 中验证 JWT 令牌吗?
- authentication - CakePHP 2.8 代码在 $this->Auth->user 中有额外的数据。如何?
- java - 深度比较数组中的每个元素
- javascript - webpack 中导入的代码是否保证在其他任何事情之前完全执行?
- html - 自定义位置的数据表分页
- java - 火花外壳 Git Bash
- php - 从php中的时间范围删除时间段