首页 > 解决方案 > SQL Server 动态 Pivot 为每个类别返回一行

问题描述

我的数据库是 SQL Server 2016。我们在 Excel 工作簿中接收源数据。包含源数据的工作表有四列。这EFFDATE对于所有负载类型和 Trans 都是通用的。这就是为什么EFFDATE.

字段名 现场数据 负载类型 反式
EFFDATE 2021 年 7 月 1 日 空值 空值
设施编号 00109 V_HFR_Input_OPRate_LabRad_PHA_R BPRH
五、NetworkCode_PHA_999 999 V_HFR_Input_OPRate_LabRad_PHA_R BPRH
五、AccomCode_3 3 V_HFR_Input_OPRate_LabRad_PHA_R BPRH
V.LAB_PHA_ReimbType 大号 V_HFR_Input_OPRate_LabRad_PHA_R BPRH
V.FFPHA_OPPassThru_LabRad V_HFR_Input_OPRate_LabRad_PHA_R BPRH
V.FFPHA_OPLCC_LabRad 0.6555 V_HFR_Input_OPRate_LabRad_PHA_R BPRH
五、类别 实验室 V_HFR_Input_OPRate_LabRad_PHA_R BPRH
五、类别 辐射度 V_HFR_Input_OPRate_LabRad_PHA_R BPRH

在处理过程中,我们有一个应用程序通过 OLEDB 连接连接到 Excel 工作簿。原始数据被加载到数据库表中,并触发触发器为字段名称和加载类型添加外键。表中数据如下

序列号 文件密钥 字段键 字段名 现场数据 加载类型键 负载类型 反式
21 1002 1 EFFDATE 2021 年 7 月 1 日 0 空值 空值
97 1002 3 设施编号 00109 16 V_HFR_Input_OPRate_LabRad_PHA_R BPRH
98 1002 29 五、NetworkCode_PHA_999 999 16 V_HFR_Input_OPRate_LabRad_PHA_R BPRH
99 1002 6 五、AccomCode_3 3 16 V_HFR_Input_OPRate_LabRad_PHA_R BPRH
100 1002 27 V.LAB_PHA_ReimbType 大号 16 V_HFR_Input_OPRate_LabRad_PHA_R BPRH
101 1002 17 V.FFPHA_OPPassThru_LabRad 16 V_HFR_Input_OPRate_LabRad_PHA_R BPRH
102 1002 15 V.FFPHA_OPLCC_LabRad 0.6555 16 V_HFR_Input_OPRate_LabRad_PHA_R BPRH
103 1002 26 五、类别 实验室 16 V_HFR_Input_OPRate_LabRad_PHA_R BPRH
104 1002 32 五、类别 辐射度 16 V_HFR_Input_OPRate_LabRad_PHA_R BPRH

我有一个存储过程,可以将源数据的行动态地旋转到单行,其中字段名称作为列标题,字段数据作为值。我对这组特定数据的问题是有两个类别,“LAB”和“RAD”。因为 SQL 数据透视需要一个聚合函数,所以我只返回一行。如果我使用PIVOT (MAX(FieldData) FOR FieldName,我会得到一行“RAD”。如果我使用PIVOT (MIN(FieldData) FOR FieldName,我会得到一行“LAB”。

如何制定查询以分别为 LAB 和 RAD 获取一行?所需的结果应与以下内容匹配。

文件密钥 序列号 加载类型键 设施代码 类别代码 网络 AccomCode 生效日期 报销类型 直通 降低成本 RatioCostChrg
1002 97 16 00109 实验室 999 3 2021 年 7 月 1 日 大号 0.6555 空值
1002 97 16 00109 辐射度 999 3 2021 年 7 月 1 日 大号 0.6555 空值

标签: sql-serveraggregate-functionsdynamic-pivot

解决方案


这是一个非常奇怪的支点,但您可以为此使用窗口条件聚合:

SELECT *
FROM (
    SELECT
      FileKey,
      SeqNo,
      LoadTypeKey,
      FacilityCode = MAX(CASE WHEN FieldName = 'FACILITYNUMBER' THEN FieldData END) OVER (PARTITION BY FileKey),
      CategoryCode = FieldData,
      Network = MAX(CASE WHEN FieldName = 'V.NetworkCode_PHA_999' THEN FieldData END) OVER (PARTITION BY FileKey),
      AccomCode = MAX(CASE WHEN FieldName = 'V.AccomCode_3' THEN FieldData END) OVER (PARTITION BY FileKey),
      EffectDate = MAX(CASE WHEN FieldName = 'EFFDATE' THEN FieldData END) OVER (PARTITION BY FileKey),
      ReimburseType = MAX(CASE WHEN FieldName = 'V.LAB_PHA_ReimbType' THEN FieldData END) OVER (PARTITION BY FileKey),
      PassThruPct = MAX(CASE WHEN FieldName = 'V.FFPHA_OPPassThru_LabRad' THEN FieldData END) OVER (PARTITION BY FileKey),
      LowerCostChrg = MAX(CASE WHEN FieldName = 'V.FFPHA_OPLCC_LabRad' THEN FieldData END) OVER (PARTITION BY FileKey)
    FROM YourTable t
) t
WHERE FieldName = 'V.Category';

推荐阅读