提问人:Living Madara 提问时间:11/7/2023 最后编辑:Adrian MaxwellLiving Madara 更新时间:11/7/2023 访问量:69
仅使用 case 语句将列转置为行并联接所有表
Transposing Columns to Rows Using only Case Statement and Joining All Tables
问:
我有一个查询,它生成了数百万行,有 10 列。我已经发布了原始查询的图片,它是我正在使用的简化版本,名为“详细信息”。
我需要将“Description”列中的每个行/值转置为分隔列,并将列:CountValue、AmountA 和 AmountB 转置为 3 个单独的表,每个表都有自己的列来自“Description”列。最后,我需要将它们全部合并到一个表中。
这是原始表详细信息:
我已将“Description”中的每个值转置到它们自己的列中,并将“CountValue”移置到一列下,并用它填充每一行。这是表计数:
在这里,我为 AmountA 做了同样的事情。这是表 AmtA:
对表 AmtB 进行了相同的转置:
最后在 Table AmountCount 中将它们连接在一起,这需要是我的最终输出:
需要注意的几点:
- 我只能使用 case 语句和聚合函数。我不能使用枢轴函数或其他更复杂的函数。
- 上面的表格只是我实际想要处理的一个示例,它有数百万行和大量列。
- 我希望所有转置表和生成的表的顺序与原始表的顺序相同。
我尝试从表 Counts 中转置 CountValue 和 Description 列的查询如下:
with Counts as
(
select distinct
t1.CountsA,
t1.CountsB,
t1.CountsC
t1.CountsD,
('CountValue') as ColCountE,
sum(case when Description = 'Arizona' then t1.CountValue end) as ColArizona,
sum(case when Description = 'California ' then t1.CountValue end) as ColCalifornia,
sum(case when Description = 'Florida' then t1.CountValue end) as ColFlorida,
sum(case when Description = 'Iowa' then t1.CountValue end) as ColIowa,
sum(case when Description = 'Kansas ' then t1.CountValue end) as ColKansas,
sum(case when Description = 'Kentucky' then t1.CountValue end) as ColKentucky
from Details t1
group by t1.CountsA,
t1.CountsB,
t1.CountsC
t1.CountsD,
CountValue
)
SELECT * from Counts
我尝试了各种分组组合,包括上述组合,但我没有得到所需的结果。如果有人能提供正确的代码,我们将不胜感激。这是我需要的主要代码,任何使用 case 语句进行转置的建议。
我的另一个问题是关于合并所有转置表。假设每个表中都存在的列 CountsA 和 CountsB 是键。在最后一个表中,如果我将所有必需的列都保留在 select 中,然后在表 Counts、AmtA 和 AmtB 中内部连接 CountsA 和 CountsB,是否可以?
答:
运行 3 个不同的查询然后联接这些结果效率不高,只需不断添加更多大小写表达式以涵盖所有金额列即可。因此,您不需要(或类似)在 select 子句中,因为所有数值列都可以在一个查询中得到满足,并且列名暗示数据源。(您可能需要重新访问列的命名,以便更清楚地说明这一点。('CountValue') as ColCountE
SELECT
t1.CountsA
, t1.CountsB
, t1.CountsC
, t1.CountsD
/* CountValue */
, sum(CASE WHEN Description = 'Arizona' THEN t1.CountValue END) AS ColArizona
, sum(CASE WHEN Description = 'California ' THEN t1.CountValue END) AS ColCalifornia
, sum(CASE WHEN Description = 'Florida' THEN t1.CountValue END) AS ColFlorida
, sum(CASE WHEN Description = 'Iowa' THEN t1.CountValue END) AS ColIowa
, sum(CASE WHEN Description = 'Kansas ' THEN t1.CountValue END) AS ColKansas
, sum(CASE WHEN Description = 'Kentucky' THEN t1.CountValue END) AS ColKentucky
/* AmountA */
, sum(CASE WHEN Description = 'Arizona' THEN t1.AmountA END) AS Arizona_A
, sum(CASE WHEN Description = 'California ' THEN t1.AmountA END) AS California_A
, sum(CASE WHEN Description = 'Florida' THEN t1.AmountA END) AS Florida_A
, sum(CASE WHEN Description = 'Iowa' THEN t1.AmountA END) AS Iowa_A
, sum(CASE WHEN Description = 'Kansas ' THEN t1.AmountA END) AS Kansas_A
, sum(CASE WHEN Description = 'Kentucky' THEN t1.AmountA END) AS Kentucky_A
/* AmountB */
, sum(CASE WHEN Description = 'Arizona' THEN t1.AmountB END) AS Arizona_B
, sum(CASE WHEN Description = 'California ' THEN t1.AmountB END) AS California_B
, sum(CASE WHEN Description = 'Florida' THEN t1.AmountB END) AS Florida_B
, sum(CASE WHEN Description = 'Iowa' THEN t1.AmountB END) AS Iowa_B
, sum(CASE WHEN Description = 'Kansas ' THEN t1.AmountB END) AS Kansas_B
, sum(CASE WHEN Description = 'Kentucky' THEN t1.AmountB END) AS Kentucky_B
FROM Details t1
GROUP BY
t1.CountsA
, t1.CountsB
, t1.CountsC
, t1.CountsD
笔记
- 在聚合函数中使用大小写表达式称为“条件聚合”
- 该子句将从您在该子句中指定的列中形成唯一的行,还会测试是否所有行都是唯一定义的 - 因此,如果已经使用 ,则它是多余的。
group by
select distinct
group by
- 不要包含需要聚合到子句中的列,包含的列有时称为“非聚合”列
group by
- 您问题的 SQL 中缺少 2 个逗号,这是我更喜欢上面看到的布局的原因。在 PoorSQL 上尝试一下,例如在选项中查找“尾随逗号”
评论