SQL过滤总和

时间:2016-11-01 18:00:21

标签: sql oracle sum having

这是我的查询,它的确有效:

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&lt;&gt;的总和。 0然后返回这些交易的所有其他数据。

我不是一个SQL人员,必须亲自完成所有这些工作,并希望对我需要做的任何帮助表示感谢。我尝试了HAVING和GROUP BY,但它不允许我在GROUP BY之后省略TRNS_AMT之后的所有字段,并且GROUP BY之后的所有字段都会导致问题,因为它们对于任何事务都不相同,因此导致在TRNS_AMT上没有过滤。

所以,在英语中,我需要首先找到哪些事务,其前17个字段组合在一起的总和不等于零,并返回非零结果的所有28个字段,其TRNS_AMT未被删除,返回给用户

2 个答案:

答案 0 :(得分:0)

您还没有提到您要查询的DBMS。我认为bellow适用于SQL Server 2012或更新版本,也许是oracle但我不确定。

我使用窗口总和来选择按所需列分组的转换量,然后选择大于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 

答案 1 :(得分: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(),称为“分析版本”,允许您仍然显示基表中的所有行,并计算所有这些列分组的“好像” - 总和对于组成组的所有行都是相同的。然后过滤掉总和为零的行。 (您需要使用分析函数来执行此操作 - HAVING条件没有模拟,只存在于“聚合版本”中。

当您从一个基表中选择所有内容时,不必使用表名称为列名添加前缀(如果这样做,请为表提供一个单字母别名,如FROM IDS.EXPENDITURES E并写入列比如E.CNTRT更容易让人眼前一亮。)