如何在聚合器转换信息中选择最小非零数?

时间:2015-11-12 16:54:48

标签: oracle11g informatica-powercenter

我已经有了聚合器转换。它根据CODE对数据进行分组,DISTANCE按降序排列。因此我们必须仅根据DISTANCE选择行。通常聚合器将最后一行作为输出。所以在CASE 1中,它是以DISTANCE = 0作为输出的最后一行,但是它必须采用具有最小非零距离的行,即DISTANCE = 25.它适用于案例2和案例3。 案例2的规则:它将选择DISTANCE = 0的最后一行。 规则3的规则:它将选择最后一行的非零DISTANCE。

案例1

CODE   APP-NO    DISTANCE
A      120         121 
A      124         25 
A      125         0
A      126         0

OUTPUT:
CODE   APP-NO    DISTANCE
A      124         25

案例2

CODE   APP-NO    DISTANCE
A      120         0 
A      124         0 
A      125         0
A      126         0

OUTPUT:
CODE   APP-NO    DISTANCE
A      120         0 

案例3

CODE   APP-NO    DISTANCE
A      120         4 
A      124         3 
A      125         2
A      126         1

OUTPUT:
CODE   APP-NO    DISTANCE
A      126         1 

2 个答案:

答案 0 :(得分:0)

如果你在第一行之后有一个非零距离或者第一个"第一个"对于所有行都有0的行,那么这应该可以解决问题:

with sample_data as (select 'A' code, 120 app_no, 0 distance from dual union all
                     select 'A' code, 124 app_no, 0 distance from dual union all
                     select 'A' code, 125 app_no, 25 distance from dual union all
                     select 'A' code, 126 app_no, 121 distance from dual union all
                     select 'B' code, 120 app_no, 0 distance from dual union all
                     select 'B' code, 124 app_no, 0 distance from dual union all
                     select 'B' code, 125 app_no, 0 distance from dual union all
                     select 'B' code, 126 app_no, 0 distance from dual union all
                     select 'C' code, 120 app_no, 1 distance from dual union all
                     select 'C' code, 124 app_no, 2 distance from dual union all
                     select 'C' code, 125 app_no, 3 distance from dual union all
                     select 'C' code, 126 app_no, 4 distance from dual)
-- end of setting up a subquery that mimics a table with data in it. See SQL below:
select code,
       app_no,
       distance
from   (select code,
               app_no,
               distance,
               row_number() over (partition by code order by distance, app_no) rn1,
               case when distance > 0 
                         then row_number() over (partition by code, case when distance > 0 then code end order by distance, app_no)
                    else null
               end rn2,
               max(distance) over (partition by code) max_distance
        from   sample_data)
where  rn2 = 1
or     (max_distance = 0 and rn1 = 1);

CODE     APP_NO   DISTANCE
---- ---------- ----------
A           125         25
B           120          0
C           120          1

要显示给定代码的所有行,其中所有行的距离为0(即情况2)而不是第一行很容易 - 您只需要从上面删除and rn1 = 1查询。

所以新查询看起来像:

with sample_data as (select 'A' code, 120 app_no, 0 distance from dual union all
                     select 'A' code, 124 app_no, 0 distance from dual union all
                     select 'A' code, 125 app_no, 25 distance from dual union all
                     select 'A' code, 126 app_no, 121 distance from dual union all
                     select 'B' code, 120 app_no, 0 distance from dual union all
                     select 'B' code, 124 app_no, 0 distance from dual union all
                     select 'B' code, 125 app_no, 0 distance from dual union all
                     select 'B' code, 126 app_no, 0 distance from dual union all
                     select 'C' code, 120 app_no, 1 distance from dual union all
                     select 'C' code, 124 app_no, 2 distance from dual union all
                     select 'C' code, 125 app_no, 3 distance from dual union all
                     select 'C' code, 126 app_no, 4 distance from dual)
-- end of setting up a subquery that mimics a table with data in it. See SQL below:
select code,
       app_no,
       distance
from   (select code,
               app_no,
               distance,
               case when distance > 0 
                         then row_number() over (partition by code, case when distance > 0 then code end order by distance, app_no)
                    else null
               end rn,
               max(distance) over (partition by code) max_distance
        from   sample_data)
where  rn = 1
or     max_distance = 0;

CODE     APP_NO   DISTANCE
---- ---------- ----------
A           125         25
B           120          0
B           124          0
B           125          0
B           126          0
C           120          1

答案 1 :(得分:0)

这将需要两个步骤:聚合以获得最小非零DISTANCE并获得相应的APP-NO。所以:

在CODE的Aggreator Transformation组中获取正确的DISTANCE

  • minNonZeroDist = MIN(DISTANCE, DISTANCE != 0)

现在,您需要使用另一个聚合器转换准备第二个管道,按CODE分组并获取正确的APP-NO。创建两个输出端口:

  • minApp = MIN(APP-NO)
  • minNonZeroDistAPP = MIN(APP-NO, DISTANCE != 0)

将两个聚合一起加入。使用以下端口创建Joiner Transformation

  • agg_CODE - 链接第一个聚合器输出CODE
  • agg_DISTANCE - 链接第一个聚合器输出DISTANCE
  • agg2_CODE - 链接第二个聚合器的CODE
  • agg2_DISTANCE - 链接DISTANCE与第二聚合器
  • agg2_minApp - 链接来自2nd Aggregator的minApp
  • agg2_minNonZeroDistAPP - 从第二个聚合器链接minNonZeroDistAPP

添加两个连接条件:

  • nonagg_CODE = agg_CODE
  • nonagg_DISTANCE = agg_DISTANCE

现在使用表达式转换来使用类似IIF(ISNULL(agg2_minNonZeroDistAPP), agg2_minApp, agg2_minNonZeroDistAPP )的公式选择正确的APP-NO。那应该解决它。

注意:确保数据在CODEDISTANCE上排序,并使用Sorted Input属性进行Joiner Transformation。