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

动态添加查询结果列:制造作业操作数据行内汇总需求

制造作业操作数据按JobNum汇总为单行记录的SQL实现

需求:将制造作业操作数据按JobNum汇总为单行记录,每个作业包含的多个操作需拼接为「操作名(实际工时/预估工时)」格式,列名统一为Operation,按操作顺序填充,空列留空。

原数据

JobNumOperationHoursEstimateCompleted
1Fabrication561
1Paint111
1Packaging010
2Fabrication660
2Welding240
2Paint020
2Packaging010
3Fabrication321
3Packaging0.250.51

期望输出

JobNumOperationOperationOperationOperation
1Fabrication (5/6)Paint (1/1)Packaging (0/1)
2Fabrication (6/6)Welding (2/4)Paint (0/2)Packaging (0/1)
3Fabrication (3/2)Packaging (0.25/0.5)

之前尝试的问题

使用PIVOT实现时,需预先定义所有操作作为列,导致每行存在大量NULL值,不符合需求:

JobNumFabricationWeldingPaintPackaging
1Fabrication (5/6)NULLPaint (1/1)Packaging (0/1)
2Fabrication (6/6)Welding (2/4)Paint (0/2)Packaging (0/1)
3Fabrication (3/2)NULLNULLPackaging (0.25/0.5)

解决方案

核心思路是先为每个JobNum下的操作生成序号,再通过条件聚合实现列转行,同时拼接目标字符串。

SQL Server 实现

WITH JobOperations AS (
    SELECT 
        JobNum,
        CONCAT(Operation, ' (', Hours, '/', Estimate, ')') AS OpText,
        -- 若有固定操作顺序,替换ORDER BY后的(SELECT NULL)为对应排序字段
        ROW_NUMBER() OVER (PARTITION BY JobNum ORDER BY (SELECT NULL)) AS OpSeq
    FROM YourTableName
)
SELECT 
    JobNum,
    MAX(CASE WHEN OpSeq = 1 THEN OpText END) AS Operation,
    MAX(CASE WHEN OpSeq = 2 THEN OpText END) AS Operation,
    MAX(CASE WHEN OpSeq = 3 THEN OpText END) AS Operation,
    MAX(CASE WHEN OpSeq = 4 THEN OpText END) AS Operation
FROM JobOperations
GROUP BY JobNum
ORDER BY JobNum;

MySQL 实现

支持动态根据最大操作数生成列:

-- 获取最大操作数
SET @max_ops = (SELECT COUNT(*) FROM (SELECT JobNum, COUNT(*) AS cnt FROM YourTableName GROUP BY JobNum) t ORDER BY cnt DESC LIMIT 1);

-- 动态拼接SQL语句
SET @sql = NULL;
SELECT GROUP_CONCAT(
    'MAX(CASE WHEN OpSeq = ', seq, ' THEN OpText END) AS Operation'
) INTO @sql
FROM (SELECT @row := @row + 1 AS seq FROM information_schema.tables, (SELECT @row := 0) r LIMIT @max_ops) t;

SET @sql = CONCAT('
WITH JobOperations AS (
    SELECT 
        JobNum,
        CONCAT(Operation, " (", Hours, "/", Estimate, ")") AS OpText,
        ROW_NUMBER() OVER (PARTITION BY JobNum ORDER BY NULL) AS OpSeq
    FROM YourTableName
)
SELECT JobNum, ', @sql, ' FROM JobOperations GROUP BY JobNum ORDER BY JobNum;
');

-- 执行动态SQL
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

PostgreSQL 实现

静态版本(已知最大操作数为4):

WITH JobOperations AS (
    SELECT 
        JobNum,
        CONCAT(Operation, ' (', Hours, '/', Estimate, ')') AS OpText,
        ROW_NUMBER() OVER (PARTITION BY JobNum ORDER BY NULL) AS OpSeq
    FROM YourTableName
)
SELECT 
    JobNum,
    MAX(CASE WHEN OpSeq = 1 THEN OpText END) AS "Operation",
    MAX(CASE WHEN OpSeq = 2 THEN OpText END) AS "Operation",
    MAX(CASE WHEN OpSeq = 3 THEN OpText END) AS "Operation",
    MAX(CASE WHEN OpSeq = 4 THEN OpText END) AS "Operation"
FROM JobOperations
GROUP BY JobNum
ORDER BY JobNum;

若需要动态生成列,可编写PL/pgSQL存储过程实现。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 19:27:22