SQL 按总和筛选

SQL Filter on sum

这是我的查询,它有效:

SELECT EXPENDITURES.CNTRT, 
EXPENDITURES.L_CNTRT, 
EXPENDITURES.BE, 
EXPENDITURES.L_BE, 
EXPENDITURES.SPGM_STD, 
EXPENDITURES.L_SPGM, 
EXPENDITURES.CAT, 
EXPENDITURES.L_CAT, 
EXPENDITURES.OCA, 
EXPENDITURES.L_OCA, 
EXPENDITURES.L2, 
EXPENDITURES.L1L5, 
EXPENDITURES.L_L1L5, 
EXPENDITURES.OBJ, 
EXPENDITURES.L_OBJ, 
EXPENDITURES.STFY, 
EXPENDITURES.CF, 
EXPENDITURES.TRNS_AMT, 
EXPENDITURES.MGDT, 
EXPENDITURES.VENDOR_ID_NO, 
EXPENDITURES.VENDOR_LONG_NAME, 
EXPENDITURES.DESCRIPTION, 
EXPENDITURES.INVOICE_NO, 
EXPENDITURES.DN, 
EXPENDITURES.OTHER_DOC_NO, 
EXPENDITURES.PRIM_DOC_NO, 
EXPENDITURES.SECOND_DOC_NO, 
EXPENDITURES.TR
 FROM IDS.EXPENDITURES EXPENDITURES
 WHERE ((EXPENDITURES.BE<>'70212349')) 
AND (EXPENDITURES.OCA LIKE '%C') 
AND (EXPENDITURES.STFY='2017') 
AND (EXPENDITURES.CF<>'C') 
AND ((EXPENDITURES.MGDT<={ts '2016-07-31 00:00:00'}) AND (EXPENDITURES.MGDT>={ts '2016-07-01 00:00:00'})) 

我被要求做的是,如果您只按 CF 以内的字段分组,则在此基础上对 TRNS_AMT 求和,然后 TRNS_AMT 的总和 < > 0 然后 return 这些交易的所有其他数据。

我不是 SQL 人,必须手动完成所有这些工作,如果对我需要做的事情有任何帮助,我将不胜感激。我尝试执行 HAVING 和 GROUP BY,但它不会让我从 GROUP BY 中省略 TRNS_AMT 之后的所有字段,并且 GROUP BY 之后的所有这些字段都是导致问题的原因,因为它们对于任何一个都不相同事务,因此不会对 TRNS_AMT.

进行过滤

因此,在英语中,我需要首先找到哪些交易(其总和由前 17 个字段组合在一起)不等于零,并且 return 非零结果的所有 28 个字段及其TRNS_AMT 未求和,给用户。

您没有提到您查询的是什么 DBMS。我认为波纹管适用于 SQL 服务器 2012 或更新版本,也许适用于 oracle,但我不确定。

我正在使用窗口总和 select 按您需要的列分组的交易金额,然后 selecting 大于 0 的金额。

您也可以在 cte 中使用常规总和,然后使用键值加入它,但我不确定这些是什么。

        WITH NonZeroTransactions AS(

            SELECT     TotalTRNSAMT =SUM(TRNS_AMT)OVER(PARTITION BY           
                                                          EXPENDITURES.CNTRT, 
                                                          EXPENDITURES.L_CNTRT, 
                                                          EXPENDITURES.BE, 
                                                          EXPENDITURES.L_BE, 
                                                          EXPENDITURES.SPGM_STD, 
                                                          EXPENDITURES.L_SPGM, 
                                                          EXPENDITURES.CAT, 
                                                          EXPENDITURES.L_CAT, 
                                                          EXPENDITURES.OCA, 
                                                          EXPENDITURES.L_OCA, 
                                                          EXPENDITURES.L2, 
                                                          EXPENDITURES.L1L5, 
                                                          EXPENDITURES.L_L1L5, 
                                                          EXPENDITURES.OBJ, 
                                                          EXPENDITURES.L_OBJ, 
                                                          EXPENDITURES.STFY, 
                                                          EXPENDITURES.CF
                                                       ORDER BY
                                                          EXPENDITURES.CNTRT
                                                       ),
    EXPENDITURES.CNTRT, 
    EXPENDITURES.L_CNTRT, 
    EXPENDITURES.BE, 
    EXPENDITURES.L_BE, 
    EXPENDITURES.SPGM_STD, 
    EXPENDITURES.L_SPGM, 
    EXPENDITURES.CAT, 
    EXPENDITURES.L_CAT, 
    EXPENDITURES.OCA, 
    EXPENDITURES.L_OCA, 
    EXPENDITURES.L2, 
    EXPENDITURES.L1L5, 
    EXPENDITURES.L_L1L5, 
    EXPENDITURES.OBJ, 
    EXPENDITURES.L_OBJ, 
    EXPENDITURES.STFY, 
    EXPENDITURES.CF, 
    EXPENDITURES.TRNS_AMT, 
    EXPENDITURES.MGDT, 
    EXPENDITURES.VENDOR_ID_NO, 
    EXPENDITURES.VENDOR_LONG_NAME, 
    EXPENDITURES.DESCRIPTION, 
    EXPENDITURES.INVOICE_NO, 
    EXPENDITURES.DN, 
    EXPENDITURES.OTHER_DOC_NO, 
    EXPENDITURES.PRIM_DOC_NO, 
    EXPENDITURES.SECOND_DOC_NO, 
    EXPENDITURES.TR
     FROM IDS.EXPENDITURES EXPENDITURES
     WHERE ((EXPENDITURES.BE<>'70212349')) 
    AND (EXPENDITURES.OCA LIKE '%C') 
    AND (EXPENDITURES.STFY='2017') 
    AND (EXPENDITURES.CF<>'C') 
    AND ((EXPENDITURES.MGDT<={ts '2016-07-31 00:00:00'}) AND (EXPENDITURES.MGDT>={ts '2016-07-01 00:00:00'}))
    )
SELECT * FROM nonZeroTransactions 
WHERE TotalTRNSAMT >0 
select *
from ( select <list all the columns here>
              , sum(trns_amt) over (partition by cntrt, l_cntrt <etc.>) as tot_trns_amt
       from   ids.expenditures
       where  <all your conditions here>
     )
where tot_trns_amt <> 0;

此版本的 sum(),称为 "analytic version",允许您仍然显示基数 table 的所有行,并计算总和 "as if"按所有这些列分组 - 组成一个组的所有行的总和将相同。然后过滤掉总和为零的行。 (你需要用解析函数来做到这一点——没有类似于 HAVING 条件的模拟,它只存在于 "aggregate version")。

当您 select 仅来自一个碱基 table 的所有内容时,没有必要在列名称前加上 table 名称(如果这样做,请将 table 一个单字母的别名,如 FROM IDS.EXPENDITURES E 并写成 E.CNTRT 这样的列以使其更容易在眼睛上看到)。