Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/82.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SAP HANA SQL中是否有任何方法可以在迭代中不进行循环操作的情况下计算%?_Sql_Hana - Fatal编程技术网

SAP HANA SQL中是否有任何方法可以在迭代中不进行循环操作的情况下计算%?

SAP HANA SQL中是否有任何方法可以在迭代中不进行循环操作的情况下计算%?,sql,hana,Sql,Hana,我有一个如下的输入表,其中有item和amount列。也有低(5%)和高(50%)的恒定值 需要通过“总额”推导“金额”的%,如果%小于低%或大于高%,则需要忽略这些记录,并通过获取这些行的总额再次计算剩余行的% 我能在不使用SAP HANA SQL中的循环操作的情况下实现这一点吗?这在大多数当前SQL RDBMS中都是可行的。 此解决方案需要通用表表达式(CTE/“WITH”子句)和窗口函数 鉴于这些情况,我们可以采取以下措施: select current_time, * from m_

我有一个如下的输入表,其中有item和amount列。也有低(5%)和高(50%)的恒定值

需要通过“总额”推导“金额”的%,如果%小于低%或大于高%,则需要忽略这些记录,并通过获取这些行的总额再次计算剩余行的%


我能在不使用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,我们需要这个逻辑来只选择那些在低%和高%边界条件内的记录。任何记录都不在边界条件内,那么我们需要重复这个过程,直到只有那些记录在边界条件内,或者没有记录。好的,这只是稍微不同的要求,但不是它的用途。只要用循环或递归来描述问题,就不太可能找到不同的方法。然而,使用所示的方法,可以保证只获得满足边界条件的记录。