ABAP CDS中分组数据集的每个组中的极值

时间:2019-10-03 18:37:20

标签: sql sap abap opensql cds

我有一个用AMDP编写的SQLScript查询,它创建了两个新列source_contracttarget_contract

RETURN SELECT client as client,
    pob_id as pob_id,
    dateto as change_to,
    datefrom as change_from,
    cast( cast( substring( cast( datefrom as char( 8 ) ), 1,4 ) as NUMBER ( 4 ) ) as INT )
        as change_year,
    cast( CONCAT( '0' , ( substring( cast( datefrom as char( 8 ) ), 5,2  ) ) ) as VARCHAR (3))
        as change_period,
    LAG( contract_id, 1, '00000000000000' ) OVER ( PARTITION BY pob_id ORDER BY pob_id, datefrom )
        as source_contract,
    contract_id as target_contract
    from  farr_d_pob_his
    ORDER BY pob_id

原始数据:

POB     Valid To    Valid From  Contract
257147  05.04.2018  05.04.2018  10002718
257147  29.05.2018  06.04.2018  10002719
257147  31.12.9999  30.05.2018  10002239

AMDP视图中的数据: enter image description here

我想忽略任何中间行(日期是决定顺序的标准)。有任何建议或想法吗?

我想到了使用Group by获取最大日期和最小日期,并在单独的消费视图中对这些条目使用并集,但是如果我们使用group by,我们将无法获取其他条目。另一种可能性是按日期排序,但在CDS中不可用。

2 个答案:

答案 0 :(得分:0)

您已经有了带有子选择的最佳解决方案。

伪代码:

SELECT *
  FROM OriginalData
  WHERE (POB, ValidFrom)
     IN (SELECT POB, MIN(ValidFrom)
          FROM OriginalData
          GROUP BY POB)
    OR (POB, ValidTo)
     IN (SELECT POB, MAX(ValidTo)
           FROM OriginalData
           GROUP BY POB);

GROUP BY将不起作用,因为它会“混淆”不同列中的最小值。

一个很好的接触可能是将子选择提取到它们自己的视图中,例如。最早的合同和最近的合同。

答案 1 :(得分:0)

这是您的任务解决方案的概念验证。

假设我们已经根据与您的表gets相似的材料类型( MTART )数据集进行了预选:

int

这里是物料,我们要在创建日期( ERSDA )之前仅保留最后一个物料( MATNR )并查找维护类型( VPSTA ),第一个和最后一个。

mara

在您的情况下,您也可以在每个 POB ------------------------------------------------ | MATNR | ERSDA | VPSTA |MTART| ------------------------------------------------ | 17000000007|18.06.2018|KEDBXCZ |ZSHD | | 17000000008|21.06.2018|K |ZSHD | | 17000000011|21.06.2018|K |ZSHD | | 17000000023|22.06.2018|KEDCBGXZLV|ZSHD | | 17000000103|09.01.2019|K |ZSHD | | 17000000104|09.01.2019|K |ZSHD | | 17000000105|09.01.2019|K |ZSHD | | 17000000113|06.02.2019|V |ZSHD | ------------------------------------------------ )源合同和目标合同 contract_id (最后------------------------------------------------ | MATNR | ERSDA | VPSTA |MTART| ------------------------------------------------ | 17000000007|18.06.2018|KEDBXCZ |ZSHD | | 17000000113|06.02.2019|V |ZSHD | ------------------------------------------------ 头)中进行搜索。 开始的标准(mtart

一个可以使用vpsta和两个带有子查询的选择来实现:

ersda

在这里您会注意到第一个选择获取最大的UNION日期,第二个选择获取最小的日期。

按类型和日期排序的结果集将是您要查找的内容(F =首先,L =最后):

enter image description here

您的SELECT应该看起来像这样:

 SELECT ersda AS date, matnr AS max, mtart AS type, vpsta AS maint
   FROM mara AS m
  WHERE ersda = ( SELECT MAX( ersda ) FROM mara WHERE mtart = m~mtart )
    UNION SELECT ersda AS date, matnr AS max, mtart AS type, vpsta AS maint
     FROM mara AS m2
    WHERE ersda = ( SELECT MIN( ersda ) FROM mara WHERE mtart = m2~mtart )
    ORDER BY type, date
     INTO TABLE @DATA(lt_result).

请注意,仅当您有唯一的ersda日期时,此方法才有效,否则查询将不知道您要使用哪个最后/第一个合同。此外,如果每个POB中只有一份合同,则只有一条记录。

关于实现的两句话。在您的示例中,我看到您使用AMDP类,但后来您提到CDS不支持 SELECT datefrom as change_from, contract_id AS contract, pob_id AS pob FROM farr_d_pob_his AS farr WHERE datefrom = ( SELECT MAX( datefrom ) FROM farr_d_pob_his WHERE pob_id = farr~pob_id ) UNION SELECT datefrom as change_from, contract_id AS contract, pob_id AS pob FROM farr_d_pob_his AS farr2 WHERE datefrom = ( SELECT MIN( datefrom ) FROM farr_d_pob_his WHERE pob_id = farr2~pob_id ) ORDER BY pob, date INTO TABLE @DATA(lt_result). 。是的,CDS和子查询不支持它们,但是AMDP支持它们。

您应区分two types of AMDP functions:AMDP方法的函数和CDS表函数的函数。第一个通过排序和子查询完美地处理SELECT。您可以在datefrom演示类中查看示例,这些示例演示了AMDP功能(包括子查询)。您可以在AMDP函数中派生代码,然后从CDS表函数实现中调用它。