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

动态SQL实现可变行转列:将Bin位置转为字段值而非列名

解决方案

要实现你需要的格式,核心是先按SalesOrder+Line分组,给每组内的Bin行分配序号,再通过动态条件聚合将每个序号对应的Bin和Qty转为固定名称的列(Bin01/QTY01...Bin03/QTY03)。以下是调整后的代码:

DECLARE @maxSeq INT = 3; -- 支持最多3组Bin/QTY,可按需修改
DECLARE @cols NVARCHAR(MAX);

-- 生成动态列列表:Bin01, QTY01, Bin02, QTY02, ..., BinN, QTYN
SET @cols = STRING_AGG(
    CONCAT('MAX(CASE WHEN seq = ', n, ' THEN Bin END) AS Bin', FORMAT(n, '00'), ',',
           'MAX(CASE WHEN seq = ', n, ' THEN StockQtyToShip END) AS QTY', FORMAT(n, '00')),
    ','
) WITHIN GROUP (ORDER BY n)
FROM (VALUES (1),(2),(3)) AS nums(n);

-- 构建动态SQL查询
DECLARE @sql NVARCHAR(MAX) = CONCAT('
SELECT 
    SalesOrder,
    SalesOrderLine AS Line,
    ', @cols, '
FROM (
    -- 给每个SalesOrder+Line分组内的行分配序号
    SELECT 
        SalesOrder,
        SalesOrderLine,
        Bin,
        StockQtyToShip,
        ROW_NUMBER() OVER(PARTITION BY SalesOrder, SalesOrderLine ORDER BY Bin) AS seq
    FROM SorDetailBin
) AS t
GROUP BY SalesOrder, SalesOrderLine
');

EXEC sp_executesql @sql;

代码说明:

  • 序号分配:用ROW_NUMBER() OVER(PARTITION BY SalesOrder, SalesOrderLine ORDER BY Bin)给同一订单行下的每个Bin分配唯一序号(1-3),确保每个Bin/QTY对对应固定的列位置。
  • 动态列生成:通过STRING_AGG拼接出所有需要的Bin和Qty列,格式为Bin01, QTY01, Bin02, QTY02...,替换硬编码列名的同时支持扩展数量。
  • 条件聚合:用MAX(CASE WHEN ...)将每个序号对应的Bin值和Qty值映射到对应的列,最终按订单行分组聚合得到目标格式。

适配现有代码的关键点:

  • 原代码错误地按Bin分区生成序号,导致无法按订单行分组;调整为按SalesOrder+SalesOrderLine分区,才是正确的分组维度。
  • 放弃直接用PIVOT(因为PIVOT只能针对单个聚合字段,无法同时处理Bin和Qty两个字段),改用条件聚合实现多字段的行转列。

如果需要支持更多组,只需修改@maxSeq的值,并在VALUES (1),(2),(3)中添加对应的数字即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 07:05:37