【问题标题】:How to use SUM and COUNT and add the results as a resulting column如何使用 SUM 和 COUNT 并将结果添加为结果列
【发布时间】:2016-06-03 04:46:20
【问题描述】:
CREATE TABLE my_table ( bank_account, bank_id, amount ) AS
SELECT 123, 600, 1500 FROM DUAL UNION ALL
SELECT 123, 600, 2500 FROM DUAL UNION ALL
SELECT 123, 600, 3500 FROM DUAL UNION ALL
SELECT 123, 700,  500 FROM DUAL UNION ALL
SELECT 123, 700, 1000 FROM DUAL UNION ALL
SELECT 456, 800, 2000 FROM DUAL UNION ALL
SELECT 456, 900, 2000 FROM DUAL UNION ALL
SELECT 456, 900, 4000 FROM DUAL;

我需要编写结果如下所示的 SQL 代码:

其中:
total_amount - 在特定 bank_id 中进行的所有交易 bank_account 的总和
number_of_transactions - 在特定 bank_id 中由 bank_account 进行的交易数 total_num_trans - bank_account 进行的交易总数
total_am_trans - bank_account 进行的交易总数

我只获得了一些我需要的结果,但无法全部获得。 这是我已经开始的:

  SELECT t.bank_account
       , t.bank_id
       , count(*)       number_of_transactions
       , sum(t.amount)  total_amount
    FROM my_table t 
GROUP BY t.bank_account
       , t.bank_id
ORDER BY t.bank_account

谢谢。

【问题讨论】:

  • 请更新您的问题以包含您预期输出的文本表示 - 并非我们所有人都能看到图像。

标签: sql oracle


【解决方案1】:

Oracle 设置

CREATE TABLE my_table ( bank_account, bank_id, amount ) AS
SELECT 123, 600, 1500 FROM DUAL UNION ALL
SELECT 123, 600, 2500 FROM DUAL UNION ALL
SELECT 123, 600, 3500 FROM DUAL UNION ALL
SELECT 123, 700,  500 FROM DUAL UNION ALL
SELECT 123, 700, 1000 FROM DUAL UNION ALL
SELECT 456, 800, 2000 FROM DUAL UNION ALL
SELECT 456, 900, 2000 FROM DUAL UNION ALL
SELECT 456, 950, 4000 FROM DUAL;

查询

SELECT bank_account,
       bank_id,
       total_amount,
       number_of_transactions,
       SUM( number_of_transactions ) OVER ( PARTITION BY bank_account ) AS total_num_trans,
       SUM( total_amount           ) OVER ( PARTITION BY bank_account ) AS total_am_trans,
       number_of_transactions
         / SUM( number_of_transactions ) OVER ( PARTITION BY bank_account )
         * 100 AS percentage_trans,
       total_amount
         / SUM( total_amount           ) OVER ( PARTITION BY bank_account )
         * 100 AS percentage_trans
FROM   (
  SELECT   bank_account,
           bank_id,
           count(*)    AS number_of_transactions,
           sum(amount) AS total_amount
  FROM     my_table
  GROUP BY bank_account
         , bank_id
)

输出

BANK_ACCOUNT    BANK_ID TOTAL_AMOUNT NUMBER_OF_TRANSACTIONS TOTAL_NUM_TRANS TOTAL_AM_TRANS PERCENTAGE_TRANS PERCENTAGE_TRANS
------------ ---------- ------------ ---------------------- --------------- -------------- ---------------- ----------------
         123        600         7500                      3               5           9000               60       83.3333333 
         123        700         1500                      2               5           9000               40       16.6666667 
         456        800         2000                      1               3           8000       33.3333333               25 
         456        900         2000                      1               3           8000       33.3333333               25 
         456        950         4000                      1               3           8000       33.3333333               50 

【讨论】:

  • 希望子查询中不需要ORDER BY bank_account
  • @Arulkumar 谢谢,已更新。不,这不是必需的,但我刚刚复制了 OP 的查询,并且在我整理它时没有删除那个位。
  • 试过了,它取得了一些成功。显然,total_num_trans 列是按 bank_id 汇总的,而不是按 bank_account 汇总的。例如:如果我们正在查看第 4 行和第 8 行,total_num_trans 应该是 6。这是我对我的数据制作的屏幕截图(很抱歉我没有按 bank_account 订购它以使其更具可读性):@ 987654321@ 应该是这样的:onedrive.live.com/…
  • @MilanStojković 我已经根据您的示例数据更新了查询的输出 - 它输出了 OP 中详述的预期值。如果没有任何其他 input 数据(格式化为 DML 语句),我无法调试更多内容,因为我无法复制您的输出。如果不是按帐户求和,请检查您在 PARTITION BY 子句中的列是否正确。
  • @MT0 你不需要 DML 声明,因为你已经完成了 :) 有了这个声明,我就得到了我需要的东西。非常感谢!
【解决方案2】:

试试这个;)

select t1.*, t2.total_num_trans, t2.total_am_trans, (t1.number_of_transactions / t2.total_num_trans) * 100 as percentage_trans, (t1.total_amount / t2.total_am_trans) * 100 as percentage_amount
from (
    select bank_account, bank_id, sum(amount) as total_amount, count(1) as number_of_transactions
        from my_table
        group by bank_account, bank_id) t1
left join (
    select bank_account, sum(total_amount) as total_am_trans, sum(number_of_transactions) as total_num_trans
    from (
        select bank_account, bank_id, sum(amount) as total_amount, count(1) as number_of_transactions
        from my_table
        group by bank_account, bank_id ) t
group by bank_account ) t2 on t1.bank_account = t2.bank_account
order by t1.bank_account

【讨论】:

  • 感谢 Reno,它提取了我真正需要的数据。唯一的问题是我必须在我从中获取数据的表非常非常大的系统中实现此语句。想象一下过去两年在银行进行的所有交易。所以如果我用双选加入,恐怕要花很多时间才能完成。感谢您的努力。
【解决方案3】:

尝试加入 2 个聚合,粗的仅按银行帐户分组,精细的也按银行 ID 分组。

      SELECT tfine.bank_account
           , tfine.bank_id
           , tfine.total_amount
           , tfine.number_of_transactions
           , tcoarse.total_num_trans
           , tcoarse.total_am_trans
        FROM (              
                  SELECT t1.bank_account
                       , t1.bank_id
                       , count(*)         number_of_transactions
                       , sum(t1.amount)   total_amount
                    FROM my_table t1 
                GROUP BY t1.bank_account
                       , t1.bank_id
             ) tfine
        JOIN (
                  SELECT t2.bank_account
                       , count(*)         total_num_trans
                       , sum(t2.amount)   total_am_trans
                    FROM my_table t2
                GROUP BY t2.bank_account
             ) tcoarse
          ON tcoarse.bank_account = tfine.bank_account
    ORDER BY tfine.bank_account
           , tfine.bank_id
           ;

在线演示on ideone.

【讨论】:

    猜你喜欢
    • 2013-04-22
    • 1970-01-01
    • 2023-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多