对 DB2 中的求和列应用列过滤器

Posted

技术标签:

【中文标题】对 DB2 中的求和列应用列过滤器【英文标题】:Apply column filter on summed columns in DB2 【发布时间】:2021-08-11 14:24:57 【问题描述】:

我有以下 DB2 表:

COLUMN_NAME DATA_TYPE TYPE_NAME COLUMN_SIZE COLUMN_TEXT
DMPROD -2 CHAR () FOR BIT DATA 35 Product Code
DMPTYP -2 CHAR () FOR BIT DATA 1 Period Type
DMTYPE -2 CHAR () FOR BIT DATA 6 Type of Data
DMVL01 3 DECIMAL 17 Value Period 1
DMVL02 3 DECIMAL 17 Value Period 2
DMVL03 3 DECIMAL 17 Value Period 3
DMVL04 3 DECIMAL 17 Value Period 4
DMVL05 3 DECIMAL 17 Value Period 5
DMVL06 3 DECIMAL 17 Value Period 6
DMVL07 3 DECIMAL 17 Value Period 7
DMVL08 3 DECIMAL 17 Value Period 8
DMVL09 3 DECIMAL 17 Value Period 9
DMVL10 3 DECIMAL 17 Value Period 10
DMVL11 3 DECIMAL 17 Value Period 11
DMVL12 3 DECIMAL 17 Value Period 12
DMYEAR 3 DECIMAL 4 Fiscal Year

以下查询将返回每个 DMTYP 的值周期总和:

   SELECT
    D.DMPROD,
    Sum(CASE WHEN DMTYPE = 'SLSGSV' THEN D.DMVL01 + D.DMVL02 + D.DMVL03 + D.DMVL04 + D.DMVL05 + D.DMVL06 + D.DMVL07 + D.DMVL08 + D.DMVL09 + D.DMVL10 + D.DMVL11 + D.DMVL12 END) AS COST,    
    Sum(CASE WHEN DMTYPE = 'RTNCST' THEN D.DMVL01 + D.DMVL02 + D.DMVL03 + D.DMVL04 + D.DMVL05 + D.DMVL06 + D.DMVL07 + D.DMVL08 + D.DMVL09 + D.DMVL10 + D.DMVL11 + D.DMVL12 END) AS RTNCST,  
    Sum(CASE WHEN DMTYPE = 'RTNNET' THEN D.DMVL01 + D.DMVL02 + D.DMVL03 + D.DMVL04 + D.DMVL05 + D.DMVL06 + D.DMVL07 + D.DMVL08 + D.DMVL09 + D.DMVL10 + D.DMVL11 + D.DMVL12 END) AS RTNNET,  
    Sum(CASE WHEN DMTYPE = 'RTNQTY' THEN D.DMVL01 + D.DMVL02 + D.DMVL03 + D.DMVL04 + D.DMVL05 + D.DMVL06 + D.DMVL07 + D.DMVL08 + D.DMVL09 + D.DMVL10 + D.DMVL11 + D.DMVL12 END) AS RTNQTY,  
    Sum(CASE WHEN DMTYPE = 'RTNVAL' THEN D.DMVL01 + D.DMVL02 + D.DMVL03 + D.DMVL04 + D.DMVL05 + D.DMVL06 + D.DMVL07 + D.DMVL08 + D.DMVL09 + D.DMVL10 + D.DMVL11 + D.DMVL12 END) AS RTNVAL,
    Sum(CASE WHEN DMTYPE = 'SLSGSV' THEN D.DMVL01 + D.DMVL02 + D.DMVL03 + D.DMVL04 + D.DMVL05 + D.DMVL06 + D.DMVL07 + D.DMVL08 + D.DMVL09 + D.DMVL10 + D.DMVL11 + D.DMVL12 END) AS SLSGSV,
    Sum(CASE WHEN DMTYPE = 'SLSLST' THEN D.DMVL01 + D.DMVL02 + D.DMVL03 + D.DMVL04 + D.DMVL05 + D.DMVL06 + D.DMVL07 + D.DMVL08 + D.DMVL09 + D.DMVL10 + D.DMVL11 + D.DMVL12 END) AS SLSLST,
    Sum(CASE WHEN DMTYPE = 'SLSNIV' THEN D.DMVL01 + D.DMVL02 + D.DMVL03 + D.DMVL04 + D.DMVL05 + D.DMVL06 + D.DMVL07 + D.DMVL08 + D.DMVL09 + D.DMVL10 + D.DMVL11 + D.DMVL12 END) AS SLSNIV,
    Sum(CASE WHEN DMTYPE = 'SLSNTN' THEN D.DMVL01 + D.DMVL02 + D.DMVL03 + D.DMVL04 + D.DMVL05 + D.DMVL06 + D.DMVL07 + D.DMVL08 + D.DMVL09 + D.DMVL10 + D.DMVL11 + D.DMVL12 END) AS SLSNTN,
    Sum(CASE WHEN DMTYPE = 'SLSQTY' THEN D.DMVL01 + D.DMVL02 + D.DMVL03 + D.DMVL04 + D.DMVL05 + D.DMVL06 + D.DMVL07 + D.DMVL08 + D.DMVL09 + D.DMVL10 + D.DMVL11 + D.DMVL12 END) AS SLSQTY,
    Sum(CASE WHEN DMTYPE = 'XXD' THEN D.DMVL01 + D.DMVL02 + D.DMVL03 + D.DMVL04 + D.DMVL05 + D.DMVL06 + D.DMVL07 + D.DMVL08 + D.DMVL09 + D.DMVL10 + D.DMVL11 + D.DMVL12 END) AS XXD
FROM
    DWM D
WHERE
    D.DMYEAR IN (2022)
    AND D.DMPTYP = 'M'
GROUP BY
    D.DMPROD
ORDER BY
    1;

输出是我想要的,除了在不重写所有总和的情况下无法在此查询中轻松更改值周期。例如,假设我只想查看 DMYEAR 2022 中的价值期 1-5,我需要更改每个案例陈述。是否有更简单的方法(可能使用子查询)来保持 SUM 语句相同但仅选择最终输出所需的值周期?

【问题讨论】:

【参考方案1】:

您可以使用子查询来解决这个问题:

SELECT
    D.DMPROD,
    Sum(CASE WHEN DMTYPE = 'SLSGSV' THEN val END) AS COST,    
    Sum(CASE WHEN DMTYPE = 'RTNCST' THEN val END) AS RTNCST,  
    Sum(CASE WHEN DMTYPE = 'RTNNET' THEN val END) AS RTNNET,  
    Sum(CASE WHEN DMTYPE = 'RTNQTY' THEN val END) AS RTNQTY,  
    Sum(CASE WHEN DMTYPE = 'RTNVAL' THEN val END) AS RTNVAL,
    Sum(CASE WHEN DMTYPE = 'SLSGSV' THEN val END) AS SLSGSV,
    Sum(CASE WHEN DMTYPE = 'SLSLST' THEN val END) AS SLSLST,
    Sum(CASE WHEN DMTYPE = 'SLSNIV' THEN val END) AS SLSNIV,
    Sum(CASE WHEN DMTYPE = 'SLSNTN' THEN val END) AS SLSNTN,
    Sum(CASE WHEN DMTYPE = 'SLSQTY' THEN val END) AS SLSQTY,
    Sum(CASE WHEN DMTYPE = 'XXD' THEN val END) AS XXD
FROM (SELECT D.*,
             (D.DMVL01 + D.DMVL02 + D.DMVL03 + D.DMVL04 + D.DMVL05) as val
      FROM DWM D
     ) D
WHERE D.DMYEAR IN (2022) AND D.DMPTYP = 'M'
GROUP BY D.DMPROD
ORDER BY 1;

【讨论】:

非常感谢,这正是我要找的【参考方案2】:

我对你想要得到的东西做了一个尝试:

   SELECT 'SLSGSV' as DMTYPE,1 as DMVL01,2 as DMVL02,3 as DMVL03,4 as DMVL04,5 as DMVL05 INTO #temptable
   DECLARE @sumvariable INT

SELECT @sumvariable = SUM(D.DMVL01 + D.DMVL02 + D.DMVL03 + D.DMVL04 + D.DMVL05) 
FROM
    #temptable D
SELECT
        CASE WHEN DMTYPE = 'SLSGSV' THEN @sumvariable END AS COST,    
        CASE WHEN DMTYPE = 'RTNCST' THEN @sumvariable END AS RTNCST,  
        CASE WHEN DMTYPE = 'RTNNET' THEN @sumvariable END AS RTNNET,  
        CASE WHEN DMTYPE = 'RTNQTY' THEN @sumvariable END AS RTNQTY,  
        CASE WHEN DMTYPE = 'RTNVAL' THEN @sumvariable END AS RTNVAL,
        CASE WHEN DMTYPE = 'SLSGSV' THEN @sumvariable END AS SLSGSV,
        CASE WHEN DMTYPE = 'SLSLST' THEN @sumvariable END AS SLSLST,
        CASE WHEN DMTYPE = 'SLSNIV' THEN @sumvariable END AS SLSNIV,
        CASE WHEN DMTYPE = 'SLSNTN' THEN @sumvariable END AS SLSNTN,
        CASE WHEN DMTYPE = 'SLSQTY' THEN @sumvariable END AS SLSQTY,
        CASE WHEN DMTYPE = 'XXD' THEN @sumvariable END AS XXD
FROM #temptable

我的理解是您将根据年份需要设置变量。

【讨论】:

以上是关于对 DB2 中的求和列应用列过滤器的主要内容,如果未能解决你的问题,请参考以下文章

过滤后如何对特定列求和

如何将空行转换为0并使用DB2对整个列求和?

通过将两列分组并对第三列数据求和来过滤python

在 pyspark 中的特定列上应用过滤器描述

更新 R Shiny 中的 DT 列过滤器选择

SparkR groupBy 多列,每个列都应用过滤器