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
这样的列以使其更容易在眼睛上看到)。
这是我的查询,它有效:
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
这样的列以使其更容易在眼睛上看到)。