SAP HANA SQL中是否有任何方法可以在迭代中不进行循环操作的情况下计算%?
我有一个如下的输入表,其中有item和amount列。也有低(5%)和高(50%)的恒定值 需要通过“总额”推导“金额”的%,如果%小于低%或大于高%,则需要忽略这些记录,并通过获取这些行的总额再次计算剩余行的%SAP HANA SQL中是否有任何方法可以在迭代中不进行循环操作的情况下计算%?,sql,hana,Sql,Hana,我有一个如下的输入表,其中有item和amount列。也有低(5%)和高(50%)的恒定值 需要通过“总额”推导“金额”的%,如果%小于低%或大于高%,则需要忽略这些记录,并通过获取这些行的总额再次计算剩余行的% 我能在不使用SAP HANA SQL中的循环操作的情况下实现这一点吗?这在大多数当前SQL RDBMS中都是可行的。 此解决方案需要通用表表达式(CTE/“WITH”子句)和窗口函数 鉴于这些情况,我们可以采取以下措施: select current_time, * from m_
我能在不使用SAP HANA SQL中的循环操作的情况下实现这一点吗?这在大多数当前SQL RDBMS中都是可行的。 此解决方案需要通用表表达式(CTE/“WITH”子句)和窗口函数 鉴于这些情况,我们可以采取以下措施:
select current_time, * from m_database;
/*
CURRENT_TIME SYSTEM_ID DATABASE_NAME HOST START_TIME VERSION USAGE
12:17:48 PM HXE HXE hxehost 02/12/2019 12:12:06.815 PM 2.00.040.00.1553674765 DEVELOPMENT
*/
create column table item_amounts (item nvarchar(10) not null
, amount integer not null);
insert into item_amounts values ('A', 10 );
insert into item_amounts values ('A', 20 );
insert into item_amounts values ('A', 30);
insert into item_amounts values ('A', 40);
insert into item_amounts values ('A', 50);
insert into item_amounts values ('A', 60);
insert into item_amounts values ('A', 70);
insert into item_amounts values ('A', 80);
insert into item_amounts values ('A', 90);
insert into item_amounts values ('A', 100);
select * from item_amounts;
/*
ITEM AMOUNT
A 10
A 20
A 30
A 40
A 50
A 60
A 70
A 80
A 90
A 100
*/
-- first round: total per group
select
item
, amount
, SUM (amount) OVER (PARTITION BY item) as item_total_amount
from
item_amounts;
/*
ITEM AMOUNT ITEM_TOTAL_AMOUNT
A 10 550
A 20 550
A 30 550
A 40 550
A 50 550
A 60 550
A 70 550
A 80 550
A 90 550
A 100 550
*/
操作说明:通常最好以可执行的形式提供测试数据,而不是作为屏幕截图或文本列表。像上面这样的东西就行了
第一步是执行简单的“%of total in a group”计算。这是一个标准要求,易于使用窗口函数实现
基于OPs示例,此实现将百分比舍入为完整整数值
select
item
, amount
, SUM (amount) OVER (PARTITION BY item) as item_total_amount
, round(100.0 * ( amount / SUM (amount) OVER (PARTITION BY item)), 0) as pct_of_item_total
from
item_amounts;
/*
ITEM AMOUNT ITEM_TOTAL_AMOUNT PCT_OF_ITEM_TOTAL
A 10 550 2
A 20 550 4
A 30 550 5
A 40 550 7
A 50 550 9
A 60 550 11
A 70 550 13
A 80 550 15
A 90 550 16
A 100 550 18
*/
现在,对于第二次“迭代”,我们应该过滤掉PCT_OF_ITEM_TOTAL在5到50之间的项目。根据新的一组项目,要求计算一个组内总金额的百分比。。。
在这里,最新情况下,我们再次看到这是完全相同的要求
果然,我们可以用完全相同的代码来实现它。
为此,我们将第一次迭代放入一个公共表表达式(此处称为stage
),并在第二次迭代的基表中使用它:
with stage as (
select
item
, amount
, SUM (amount)
OVER (PARTITION BY item) as item_total_amount
, round(100.0 *
( amount / SUM (amount)
OVER (PARTITION BY item))
, 0) as pct_of_item_total
from
item_amounts)
select
s.item
, s.amount
, SUM (s.amount)
OVER (PARTITION BY s.item) as item_total_amount
, round(100.0 *
( s.amount / SUM (s.amount)
OVER (PARTITION BY s.item))
, 0) as pct_of_item_total
from
stage s
where
s.pct_of_item_total between 5 and 50;
/*
ITEM AMOUNT ITEM_TOTAL_AMOUNT PCT_OF_ITEM_TOTAL
A 30 520 6
A 40 520 8
A 50 520 10
A 60 520 12
A 70 520 13
A 80 520 15
A 90 520 17
A 100 520 19
*/
已经是这样了。不需要循环,甚至不使用HANA特定功能。嗨,Lars,感谢您的即时帮助。提供的答案将进行两次迭代。将此扩展为多个迭代是否可行?您可以随时在结果集上重复此查询。然而,这两次迭代正是您所要求的。如果你解释一下这是为什么,也许会得到更好的答案。嗨,Lars,我们需要这个逻辑来只选择那些在低%和高%边界条件内的记录。任何记录都不在边界条件内,那么我们需要重复这个过程,直到只有那些记录在边界条件内,或者没有记录。好的,这只是稍微不同的要求,但不是它的用途。只要用循环或递归来描述问题,就不太可能找到不同的方法。然而,使用所示的方法,可以保证只获得满足边界条件的记录。