我有一个场景,我需要显示每日交易以及该月份的总交易日期和其他字段,如类型,产品等。 一旦我有了这个,主要的要求是获得该月的每日总百分比,下面就是一个例子。 1月1日的交易和1月的257的交易和1月1日的百分比是(3/257)* 100,同样10是2月1日,百分比是(10/257),依此类推。 任何人都可以帮我解决SQL查询问题吗?
Date Type Transaction Total_For_month Percentage
1/1/2017 A 3 257 1%
1/2/2017 B 10 257 4%
1/3/2017 A 5 257 2%
1/4/2017 C 8 257 3%
1/5/2017 D 12 257 5%
1/6/2017 D 17 257 7%
答案 0 :(得分:0)
使用窗口功能:
select t.*,
sum(transaction) over (partition by to_char(date, 'YYYY-MM')) as total_for_month,
transaction / sum(transaction) over (partition by to_char(date, 'YYYY-MM')) as ratio
from t;
答案 1 :(得分:0)
DATE和TYPE是Oracle关键字,我希望你不要将它们作为列名使用。我将在下面使用DT和TP。
你没有说过这种或那种方式,但似乎你必须过滤你的数据,以便最终报告是一个月(而不是一整年,比如说)。如果是这样,你可以做这样的事情。注意分析函数RATIO_TO_REPORT
。请注意,我将比率乘以100,并使用一些非标准格式来获得“百分比”格式的结果;如果从第一次阅读中不理解那部分,请不要太担心。
select dt, tp, transaction, sum(transaction) over () as total_trans_for_month,
to_char(100 * ratio_to_report(transaction) over (), '90.0L',
'nls_currency=%') as pct_of_monthly_trans
from your_table
where dt >= date '2017-01-01' and dt < add_months(date '2017-01-01', 1)
order by dt -- if needed (add more criteria as appropriate).
请注意分析条款:over ()
。我们没有任何分区,我们也没有任何订单;但由于我们希望每一行输入都在输出中生成一行,我们仍然需要总和的分析版本和分析函数ratio_to_report
。实现此目的的正确方法是包含over
子句,但将其留空:over ()
。
另请注意,在where
子句中,我没有在dt
或trunc
或任何其他函数中包裹to_char
。如果幸运的话,该列上有一个索引,如果优化程序发现它应该是,那么写where
条件允许使用该索引。
日期'2017-01-01'是任意的(选择与您的例子相符);在生产中它应该是一个绑定变量。