You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

将两列透视值转为列名:SQL透视/逆透视结果不符求助

看起来你在处理SQL的行列转换时遇到了点小麻烦,我帮你调整一下查询语句,正好能得到你想要的结果!

原始数据表

先确认一下你的基础数据源:

RowNamesCol1RowNamesCol2Col1Col2
Col1Row1Col2Row114
Col1Row2Col2Row225
Col1Row3Col2Row336

你的需求回顾

你之前的查询语句得到的结果结构不符合预期,你想要的最终输出是:

Col1Row1Col1Row2Col1Row3
RNC1Col2Row1Col2Row2Col2Row3
Col1123
Col2456

正确的SQL实现方案

核心思路是先把列转成行(UNPIVOT),再把指定的行转成列(PIVOT),最后单独生成标题行并合并到结果中。这里给出完整的可执行SQL:

WITH UnpivotedData AS (
    -- 第一步:把Col1、Col2转成行,得到列名和对应值
    SELECT 
        RowNamesCol1,
        colnames,
        colvalues
    FROM PivUnPiv1
    UNPIVOT (
        colvalues FOR colnames IN (Col1, Col2)
    ) AS Unpvt
),
PivotedValues AS (
    -- 第二步:把RowNamesCol1转成列,得到数据行的结构
    SELECT 
        colnames AS RowHeader,
        [Col1Row1], [Col1Row2], [Col1Row3]
    FROM UnpivotedData
    PIVOT (
        MAX(colvalues) FOR RowNamesCol1 IN ([Col1Row1], [Col1Row2], [Col1Row3])
    ) AS Pvt
),
HeaderRow AS (
    -- 第三步:单独生成第一行的标题行,对应RowNamesCol2的值
    SELECT 
        'RNC1' AS RowHeader,
        [Col1Row1], [Col1Row2], [Col1Row3]
    FROM PivUnPiv1
    PIVOT (
        MAX(RowNamesCol2) FOR RowNamesCol1 IN ([Col1Row1], [Col1Row2], [Col1Row3])
    ) AS PvtHeader
)
-- 最后合并标题行和数据行,并排序保证顺序
SELECT * FROM HeaderRow
UNION ALL
SELECT * FROM PivotedValues
ORDER BY 
    CASE RowHeader WHEN 'RNC1' THEN 0 ELSE 1 END,
    RowHeader;

方案解释

  1. UnpivotedData:将原始表中Col1Col2这两列的数值转成行记录,这样我们可以统一处理每一个单元格的值。
  2. PivotedValues:把RowNamesCol1的各个值转成列,同时将colnames作为行标题,得到我们需要的数据行部分。
  3. HeaderRow:专门生成第一行的标题,把每个RowNamesCol1对应的RowNamesCol2值填充到对应列中,行标题设为RNC1
  4. 合并排序:用UNION ALL把标题行和数据行合并,再通过ORDER BY确保标题行在最顶部,数据行按列名排序。

执行这段SQL后,就能得到你期望的完美结果啦!

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

火山引擎 最新活动