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

如何在SQL中对两列执行Pivot操作?求技术帮助

同时处理计划日期和实际日期的SQL透视方案

核心思路是先把**计划日期(plan_date)和实际日期(actual_date)**这两列转成行数据(逆透视),统一成「日期类型+日期值」的结构,再一次性完成透视操作,避免单独处理两列的麻烦。

示例场景说明

假设你的原始数据表project_data结构如下(贴合报表常见场景):

project_idtask_nameplan_dateactual_datecompletion_rate
1需求分析2024-01-102024-01-12100%
1开发2024-01-152024-01-1890%
2测试2024-01-202024-01-21100%

方案1:适用于支持UNPIVOT的数据库(如SQL Server)

第一步:逆透视(UNPIVOT)

先把plan_date和actual_date拆成两行,标记日期类型:

SELECT 
    project_id,
    task_name,
    date_type,
    date_value,
    completion_rate
FROM project_data
UNPIVOT (
    date_value FOR date_type IN (plan_date, actual_date)
) AS unpvt;

执行后会得到结构统一的行数据,每条原始记录拆分为「计划日期」「实际日期」两行。

第二步:透视生成报表

根据报表需求选择不同的聚合逻辑:

需求A:按日期统计计划/实际任务数量

SELECT 
    date_value AS 日期,
    ISNULL([plan_date], 0) AS 计划任务数,
    ISNULL([actual_date], 0) AS 实际完成任务数
FROM (
    SELECT 
        date_value,
        date_type
    FROM project_data
    UNPIVOT (
        date_value FOR date_type IN (plan_date, actual_date)
    ) AS unpvt
) AS src
PIVOT (
    COUNT(date_type)
    FOR date_type IN ([plan_date], [actual_date])
) AS pvt
ORDER BY date_value;

需求B:按任务展示计划/实际日期及完成率

SELECT 
    task_name AS 任务名称,
    [plan_date] AS 计划日期,
    [actual_date] AS 实际日期,
    completion_rate AS 完成率
FROM (
    SELECT 
        task_name,
        date_type,
        date_value,
        completion_rate
    FROM project_data
    UNPIVOT (
        date_value FOR date_type IN (plan_date, actual_date)
    ) AS unpvt
) AS src
PIVOT (
    MAX(date_value)
    FOR date_type IN ([plan_date], [actual_date])
) AS pvt;

方案2:适用于不支持UNPIVOT的数据库(如MySQL)

用UNION ALL替代逆透视,再用CASE WHEN实现透视:

需求A:按日期统计计划/实际任务数量

SELECT 
    date_value AS 日期,
    SUM(CASE WHEN date_type = 'plan_date' THEN 1 ELSE 0 END) AS 计划任务数,
    SUM(CASE WHEN date_type = 'actual_date' THEN 1 ELSE 0 END) AS 实际完成任务数
FROM (
    SELECT 
        plan_date AS date_value,
        'plan_date' AS date_type
    FROM project_data
    UNION ALL
    SELECT 
        actual_date AS date_value,
        'actual_date' AS date_type
    FROM project_data
) AS src
WHERE date_value IS NOT NULL
GROUP BY date_value
ORDER BY date_value;

需求B:按任务展示计划/实际日期及完成率

SELECT 
    task_name AS 任务名称,
    MAX(CASE WHEN date_type = 'plan_date' THEN date_value END) AS 计划日期,
    MAX(CASE WHEN date_type = 'actual_date' THEN date_value END) AS 实际日期,
    MAX(completion_rate) AS 完成率
FROM (
    SELECT 
        task_name,
        'plan_date' AS date_type,
        plan_date AS date_value,
        completion_rate
    FROM project_data
    UNION ALL
    SELECT 
        task_name,
        'actual_date' AS date_type,
        actual_date AS date_value,
        completion_rate
    FROM project_data
) AS src
GROUP BY task_name;

注意事项

  • 聚合函数选择:取日期值用MAX/MIN,计数用COUNT,数值求和/求平均用SUM/AVG
  • 空值处理:用ISNULL(SQL Server)或COALESCE(通用)替换NULL,保证报表美观
  • 字段适配:如果你的表结构和示例不同,只需替换对应的表名、字段名即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 15:19:58