我有一个输入表,如下所示,其中包含项目和金额列。并且还具有低(5%)和高(50%)恒定值。
需要通过“总计”得出“金额”的百分比,并且如果%小于Low%或大于high%,则需要忽略这些记录,并通过取这些行的总数再次计算剩余行的%。
如果不在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
*/
OP的注意事项:通常,最好以可执行形式提供测试数据,而不是以屏幕截图或文本列表的形式提供。像上面的事情会做。
第一步是执行简单的“一组中的总数的百分比”计算。这是标准要求,易于通过窗口功能实现。
基于OP示例,此实现将百分比四舍五入为完整的整数值。
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之间的项目。基于新的set项目,要求是计算“组内总百分比”。 。最迟在这里,我们再次看到这是exact same要求。
当然,我们可以使用exact same代码实现它。为此,我们将第一个迭代放入一个公共表表达式(在此称为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特定功能。