You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MSSQL SELECT查询动态生成日期列 按月统计订购及收费金额

MSSQL动态按月份生成订购/收费汇总列实现方案

方案1:静态聚合(适用固定统计时间范围场景)

如果你的统计月份范围是固定的,直接用CASE WHEN聚合即可,语法稳定可直接作为子查询关联其他表:

SELECT 
    vID,
    SUM(CASE WHEN month_col = 'JAN2021O' THEN value ELSE 0 END) AS JAN2021O,
    SUM(CASE WHEN month_col = 'JAN2021C' THEN value ELSE 0 END) AS JAN2021C,
    SUM(CASE WHEN month_col = 'FEB2021O' THEN value ELSE 0 END) AS FEB2021O,
    SUM(CASE WHEN month_col = 'FEB2021C' THEN value ELSE 0 END) AS FEB2021C,
    SUM(CASE WHEN month_col = 'MAR2022O' THEN value ELSE 0 END) AS MAR2022O,
    SUM(CASE WHEN month_col = 'MAR2022C' THEN value ELSE 0 END) AS MAR2022C
FROM (
    SELECT 
        vID,
        value,
        -- 生成列名:3位月份缩写+年份+类型
        LEFT(UPPER(DATENAME(MONTH, CONVERT(DATE, [date], 103))), 3) 
        + CAST(YEAR(CONVERT(DATE, [date], 103)) AS VARCHAR(4)) 
        + UPPER(type) AS month_col
    FROM 你的业务表名
) AS t
GROUP BY vID

方案2:动态PIVOT(适用自动匹配所有存在数据月份场景)

如果需要自动识别表中所有存在数据的月份生成列,用动态SQL实现:

DECLARE 
    @column_list NVARCHAR(MAX),
    @dynamic_sql NVARCHAR(MAX)

-- 第一步:生成所有需要的列名列表
SELECT @column_list = COALESCE(@column_list + ', ', '') + QUOTENAME(month_col)
FROM (
    SELECT DISTINCT 
        LEFT(UPPER(DATENAME(MONTH, CONVERT(DATE, [date], 103))), 3) 
        + CAST(YEAR(CONVERT(DATE, [date], 103)) AS VARCHAR(4)) 
        + UPPER(type) AS month_col,
        -- 用于列排序的时间维度
        DATEFROMPARTS(YEAR(CONVERT(DATE, [date], 103)), MONTH(CONVERT(DATE, [date], 103)), 1) AS sort_date,
        UPPER(type) AS sort_type
    FROM 你的业务表名
    -- 可在此处添加时间范围过滤条件,比如WHERE [date] >= '2021-01-01'
) AS t
-- 按时间先后排序,同一月份O列在前C列在后
ORDER BY sort_date ASC, sort_type DESC

-- 第二步:拼接完整PIVOT查询语句
SET @dynamic_sql = N'
SELECT *
FROM (
    SELECT 
        vID,
        value,
        LEFT(UPPER(DATENAME(MONTH, CONVERT(DATE, [date], 103))), 3) 
        + CAST(YEAR(CONVERT(DATE, [date], 103)) AS VARCHAR(4)) 
        + UPPER(type) AS month_col
    FROM 你的业务表名
) AS source_data
PIVOT (
    SUM(value) -- 按vID+月份+类型汇总金额
    FOR month_col IN (' + @column_list + N')
) AS pivot_result'

-- 执行动态查询
EXEC sp_executesql @dynamic_sql

注意事项

  • 代码中CONVERT(DATE, [date], 103)是适配样例中dd.mm.yyyy格式的字符串日期,如果你的表中date字段本身是DATE/DATETIME类型,可直接去掉转换逻辑使用字段本身。
  • 空值默认返回NULL,如果需要显示为0,可以在生成@column_list时同步拼接ISNULL(列名, 0) AS 列名的逻辑。

关联其他查询的方法

静态方案关联

直接将整个聚合查询作为子查询,和其他表做JOIN即可:

SELECT * 
FROM 你的其他查询表 o
JOIN (
    -- 上面的静态聚合查询完整代码
) AS p ON o.vID = p.vID

动态方案关联

修改动态SQL,将PIVOT结果写入临时表后再做关联:

-- 动态SQL调整为将结果写入临时表
SET @dynamic_sql = N'
SELECT * INTO #pivot_result
FROM (
    SELECT 
        vID,
        value,
        LEFT(UPPER(DATENAME(MONTH, CONVERT(DATE, [date], 103))), 3) 
        + CAST(YEAR(CONVERT(DATE, [date], 103)) AS VARCHAR(4)) 
        + UPPER(type) AS month_col
    FROM 你的业务表名
) AS source_data
PIVOT (
    SUM(value)
    FOR month_col IN (' + @column_list + N')
) AS pivot_result

-- 关联其他表
SELECT * FROM #pivot_result p
JOIN 你的其他查询表 o ON p.vID = o.vID'

EXEC sp_executesql @dynamic_sql

内容的提问来源于stack exchange,提问作者Suiseidl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 18:45:00