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

寻求CTE技术帮助:实现按子类别展示记录表头名称

解决类别-子类别行转列的CTE实现方案

看起来你现在的SQL只是实现了类别名称仅在组内第一行显示,但没达到「把子类别描述作为表头(列名)」的需求。我来帮你调整成符合预期的方案,核心是用CTE配合动态行转列来实现——因为子类别数量可能不固定,动态SQL能适配不同的子类别情况。

步骤1:明确需求逻辑

先对齐下你要的效果:

  • 每个主类别单独占一行
  • 每个子类别作为单独的列,列名就是子类别SubDescription的内容
  • 列值对应子类别的IsOMExceptionRequired/IsAMB/IsARS属性(这里默认用IsOMExceptionRequired的YES/N/A格式,你可以按需替换)

步骤2:动态行转列的CTE实现方案

先保留你原来的临时表创建逻辑,再用CTE整理数据,最后通过动态SQL完成行转列:

-- 保留你原有的临时表创建与数据插入逻辑
DROP TABLE IF EXISTS #temp 
CREATE TABLE #temp ( 
    [Description] VARCHAR(100), 
    SubDescription VARCHAR(100), 
    IsOMExceptionRequired bit,
    IsAMB bit,
    IsARS bit,
    escalationtypeid int, 
    CategorySortOrder int, 
    SubcategorySortorder int
); 

INSERT INTO #temp ([Description], SubDescription, IsOMExceptionRequired ,IsAMB,IsARS,escalationtypeid,CategorySortOrder,SubcategorySortorder) 
SELECT 
    C.Description,
    s.Description, 
    S.IsOMExceptionRequired,
    s.IsAMB,
    s.IsARS,
    CEM.escalationtypeid, 
    c.SortOrder,
    s.SortOrder 
FROM category C 
INNER JOIN SubCategory S on C.CategoryID =S.CategoryID 
INNER JOIN CategoryEscalationTypeMap CEM on CEM.CategoryID= C.CategoryID 
WHERE CEM.escalationtypeid=3 
  AND CEM.IsActive =1 
  AND C.IsActive=1 
  AND S.IsActive=1 
ORDER BY CEM.escalationtypeid, C.sortorder,S.sortorder;

-- 定义变量存储动态列名和SQL语句
DECLARE @cols NVARCHAR(MAX), @sql NVARCHAR(MAX);

-- 用CTE统一整理基础数据,预处理属性格式
WITH CategorySubData AS (
    SELECT 
        [Description] AS CategoryName,
        SubDescription,
        -- 把布尔值转成你需要的YES/N/A格式
        CASE WHEN IsOMExceptionRequired = 1 THEN 'YES' ELSE 'N/A' END AS OMExceptionStatus,
        IsAMB,
        IsARS,
        escalationtypeid,
        CategorySortOrder,
        SubcategorySortorder
    FROM #temp
)
-- 自动生成所有子类别对应的列名(适配SQL Server 2017+)
SELECT @cols = STRING_AGG(QUOTENAME(SubDescription), ', ')
FROM (SELECT DISTINCT SubDescription FROM CategorySubData) AS Subs;

-- 拼接动态行转列SQL
SET @sql = N'
SELECT 
    CategoryName,
    escalationtypeid,
    CategorySortOrder,
    ' + @cols + N'
FROM (
    SELECT 
        CategoryName,
        SubDescription,
        OMExceptionStatus, -- 要展示IsAMB/IsARS的话,直接替换成对应字段即可
        escalationtypeid,
        CategorySortOrder
    FROM CategorySubData
) AS SourceData
PIVOT (
    MAX(OMExceptionStatus) -- 因为每个类别+子类别是唯一组合,MAX不影响原始值
    FOR SubDescription IN (' + @cols + N')
) AS PivotData
ORDER BY CategorySortOrder, escalationtypeid;
';

-- 执行动态SQL
EXEC sp_executesql @sql;

关键细节说明

  1. CTE的作用:CategorySubData CTE用来统一预处理数据,比如把布尔类型的属性转换成你需要的文本格式,避免后续重复处理。
  2. 动态列生成:用STRING_AGG自动收集所有唯一的子类别名称,转成带引号的列名,避免列名包含特殊字符导致的语法错误。
  3. PIVOT函数:核心是把纵向的子类别记录转成横向的列,用MAX聚合是因为每个主类别+子类别是唯一组合,聚合函数不会改变原始值。
  4. 灵活适配:如果需要展示IsAMB或IsARS,只需要把OMExceptionStatus替换成对应的字段即可。

子类别数量固定的静态方案(可选)

如果你的子类别数量是固定的,也可以用静态PIVOT+CTE实现,不用动态SQL:

WITH CategorySubData AS (
    SELECT 
        [Description] AS CategoryName,
        SubDescription,
        CASE WHEN IsOMExceptionRequired = 1 THEN 'YES' ELSE 'N/A' END AS OMExceptionStatus,
        escalationtypeid,
        CategorySortOrder
    FROM #temp
)
SELECT 
    CategoryName,
    escalationtypeid,
    CategorySortOrder,
    [子类别A], [子类别B], [子类别C] -- 替换成你的实际子类别名称
FROM CategorySubData
PIVOT (
    MAX(OMExceptionStatus)
    FOR SubDescription IN ([子类别A], [子类别B], [子类别C])
) AS PivotData
ORDER BY CategorySortOrder;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:26:17