SQL Server - CASE 语句上的 PIVOT
Posted
技术标签:
【中文标题】SQL Server - CASE 语句上的 PIVOT【英文标题】:SQL Server - PIVOT on CASE statement 【发布时间】:2017-09-21 14:16:38 【问题描述】:我有一张这样的桌子:
Store Holiday Date_Index Temp
123 XMAS t_0 34.9
234 XMAS t_1 M
123 XMAS t_1 22.3
123 XMAS t_2 28.5
我正在尝试将其转换为这样的内容:
Store Holiday t_0 t_1 t_2
123 XMAS 34.9 22.3 28.5
234 XMAS 32.1 NULL 29.5
通过使用:
Select *
from
(
select Store, Holiday, Date_Index, Temp
from myTable
)
PIVOT
(
sum(CASE WHEN ISNUMERIC(Temp) = 1 THEN cast(Temp as decimal) ELSE NULL END)
FOR DATE_INDEX IN ([t_0],[t_1],[t_2])
) as PivotTable;
我的问题是 Temp 列包含字母和数字的混合。我试图以 case 语句的总和为中心,但收到一条错误消息。如何正确补偿非数字字符?
【问题讨论】:
【参考方案1】:你不能那样做。但是,您可以像这样在锚查询中执行此操作:
Select *
from
(
select Store, Holiday, Date_Index,
CASE WHEN ISNumeric(Temp) = 1 THEN CAST(Temp AS DECIMAL(10, 2)) ELSE 0 END AS Temp
from myTable
) as t
PIVOT
(
sum(Temp)
FOR DATE_INDEX IN ([t_0],[t_1],[t_2])
) as P;
我使用 ISNUMERIC
内置函数将那些非数值替换为 0 并将整个列转换为枢轴之前的 decimal
。然后在pivot
中使用SUM(temp)
。
demo
结果:
| Store | Holiday | t_0 | t_1 | t_2 |
|-------|---------|--------|------|--------|
| 123 | XMAS | 34.9 | 22.3 | 28.5 |
| 234 | XMAS | (null) | 0 | (null) |
【讨论】:
【参考方案2】:一种方法是:不是直接从表中选择/透视,而是从 CTE 中选择,该 CTE 将所有非数字 Temp
值替换为 NULL
。
【讨论】:
【参考方案3】:这是另一种相同的方法,可能是更简单的方法 -
SELECT Store
,Holiday
,MAX(CASE WHEN Date_Index = 't_0' THEN Temp END) AS t_0
,MAX(CASE WHEN Date_Index = 't_1' THEN Temp END) AS t_1
,MAX(CASE WHEN Date_Index = 't_2' THEN Temp END) AS t_2
FROM YOUR_TABLE
GROUP BY Store
,Holiday
【讨论】:
以上是关于SQL Server - CASE 语句上的 PIVOT的主要内容,如果未能解决你的问题,请参考以下文章
在 SQL Server 中的 case 语句中寻找解决方案