sql - 如何通过在 MSSQL 中使用 Pivot with Month 获取评级列的值及其对每个特定月份的定义

标签 sql sql-server tsql group-by pivot

示例:

数据:

GraphDetails
|----------------------------------------------------------|
| Id  GoalId  Definition                Rating  DateCrated |
| -------------------------------------------------------- |
| 1   2       Zero Infra Back Log       100     2020-02-05 |
| 2   2       Happy Customers           95      2020-02-05 |
| 3   2       Complete All Projects     100     2020-02-05 |
| 4   1       Zero Infra Back Log       100     2020-02-05 |
| 5   1       Happy Customers           98      2020-02-05 |
| 6   1       Complete All Projects     100     2020-02-05 |
|----------------------------------------------------------|

查询:

SELECT
 [1] AS Jan,
 [2] AS Feb,
 [3] AS Mar,
 [4] AS Apr,
 [5] AS May,
 [6] AS Jun,
 [7] AS Jul,
 [8] AS Aug,
 [9] AS Sep,
 [10] AS Oct,
 [11] AS Nov,
 [12] AS [Dec]
FROM
(Select Id, MONTH(DateRecorded) as TMonth
  FROM GraphDetails
    WHERE YEAR(DateRecorded) = 2020 AND GoalId = 1
    ) source
PIVOT
( Definition, Rating
    FOR TMonth
    IN ( [1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12] ) 
) AS pvtMonth

我收到此错误:

',' 附近的语法不正确。

符合“定义、评级”

结果应如下所示:

|-------------------------------------------------------------------------------------------------|
| Definition              | Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec |
|-------------------------------------------------------------------------------------------------|
| Zero Infra Back Log     | 0   | 100 | 0   | 0   | 0   | 0   | 0   | 0   | 0   | 0   | 0   | 0   |
| Happy Customers         | 0   | 98  | 0   | 0   | 0   | 0   | 0   | 0   | 0   | 0   | 0   | 0   |
| Complete All Projects   | 0   | 100 | 0   | 0   | 0   | 0   | 0   | 0   | 0   | 0   | 0   | 0   |
|-------------------------------------------------------------------------------------------------|

这可能吗? 请帮忙!

谢谢!

*以上代码基于PIVOT with MONTH()

最佳答案

您可以只使用条件聚合:

select 
    definition,
    sum(case 
        when dateRecorded >= datefromparts(2020, 1, 1) and dateRecorded < datefromparts(2020, 2, 1)
        then rating
        else 0
    end) Jan,
    sum(case 
        when dateRecorded >= datefromparts(2020, 2, 1) and dateRecorded < datefromparts(2020, 3, 1)
        then rating
        else 0
    end) Feb,
    ...
    sum(case 
        when dateRecorded >= datefromparts(2020, 12, 1) and dateRecorded < datefromparts(2021, 1, 1)
        then rating
        else 0
    end) Dec
from graphDetails
where dateRecorded >= datefromparts(2020, 1, 1) and dateRecorded < datefromparts(2021, 1, 1)
group by definition
order by definition

这种语法在某种程度上比特定的 PIVOT 运算符更灵活(而且,就其值(value)而言,它适用于不同的数据库产品)。

请注意,我修改了日期过滤器,因此它使用半开间隔,并且没有日期函数应用于列 dateRecorded:这应该允许数据库利用日期索引列(并且还可以顺利处理 dateCreated 的时间部分,如果有的话)。

关于sql - 如何通过在 MSSQL 中使用 Pivot with Month 获取评级列的值及其对每个特定月份的定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60259959/

相关文章:

sql - 基于逻辑 AND 而不是逻辑 OR 查找关联

sql - 如何有效地防止更新触发器中除一列之外的所有列?

sql-server - SQL Server 中的负数据库 ID

sql-server - 由于不存在的文件中的语法错误,数据库项目构建失败

sql - LTRIM(RTRIM(column_name)) 和 RTRIM(LTRIM(column_name)) 之间的性能有区别吗

在同一个表中具有两列的 SQL Server 不同查询

sql - 在 SQL 数据库中存储 DICOM 图像的文件位置

c# - 从 .net 代码停止 SQL 查询执行

c# - SQL CROSS JOIN问题

sql-server - 递归 CTE 中的 TSQL GROUP BY