SQL Server 动态 Pivot 为每个类别返回一行
Posted
技术标签:
【中文标题】SQL Server 动态 Pivot 为每个类别返回一行【英文标题】:SQL Server dynamic Pivot to return one row for each category 【发布时间】:2021-09-30 02:53:56 【问题描述】:我的数据库是 SQL Server 2016。我们在 Excel 工作簿中接收源数据。包含源数据的工作表有四列。 EFFDATE
适用于所有负载类型和 Trans。这就是EFFDATE
的列为空的原因。
FieldName | FieldData | LoadType | Trans |
---|---|---|---|
EFFDATE | 7/1/2021 | NULL | NULL |
FACILITYNUMBER | 00109 | V_HFR_Input_OPRate_LabRad_PHA_R | BPRH |
V.NetworkCode_PHA_999 | 999 | V_HFR_Input_OPRate_LabRad_PHA_R | BPRH |
V.AccomCode_3 | 3 | V_HFR_Input_OPRate_LabRad_PHA_R | BPRH |
V.LAB_PHA_ReimbType | L | 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.Category | LAB | V_HFR_Input_OPRate_LabRad_PHA_R | BPRH |
V.Category | RAD | V_HFR_Input_OPRate_LabRad_PHA_R | BPRH |
在处理过程中,我们有一个应用程序通过 OLEDB 连接连接到 Excel 工作簿。原始数据被加载到数据库表中,触发器触发为字段名称和加载类型添加外键。表中数据如下所示
SeqNo | FileKey | FieldKey | FieldName | FieldData | LoadTypeKey | LoadType | Trans |
---|---|---|---|---|---|---|---|
21 | 1002 | 1 | EFFDATE | 7/1/2021 | 0 | NULL | NULL |
97 | 1002 | 3 | FACILITYNUMBER | 00109 | 16 | V_HFR_Input_OPRate_LabRad_PHA_R | BPRH |
98 | 1002 | 29 | V.NetworkCode_PHA_999 | 999 | 16 | V_HFR_Input_OPRate_LabRad_PHA_R | BPRH |
99 | 1002 | 6 | V.AccomCode_3 | 3 | 16 | V_HFR_Input_OPRate_LabRad_PHA_R | BPRH |
100 | 1002 | 27 | V.LAB_PHA_ReimbType | L | 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 | V.Category | LAB | 16 | V_HFR_Input_OPRate_LabRad_PHA_R | BPRH |
104 | 1002 | 32 | V.Category | RAD | 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 获取一行?所需的结果应与以下匹配。
FileKey | SeqNo | LoadTypeKey | FacilityCode | CategoryCode | Network | AccomCode | EffectDate | ReimburseType | PassThruPct | LowerCostChrg | RatioCostChrg |
---|---|---|---|---|---|---|---|---|---|---|---|
1002 | 97 | 16 | 00109 | LAB | 999 | 3 | 7/1/2021 | L | 0.6555 | NULL | |
1002 | 97 | 16 | 00109 | RAD | 999 | 3 | 7/1/2021 | L | 0.6555 | NULL |
【问题讨论】:
【参考方案1】:这是一个非常奇怪的支点,但您可以为此使用窗口条件聚合:
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';
【讨论】:
以上是关于SQL Server 动态 Pivot 为每个类别返回一行的主要内容,如果未能解决你的问题,请参考以下文章