1

我有一个用 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 视图中的数据: 在此处输入图像描述

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

我想过使用Group by来获取最大日期和最小日期,并在单独的消费视图中对这些条目使用联合,但如果我们正在使用group by,我们将无法获取其他条目。另一种可能性是按日期订购,但它在 CDS 中不可用。

4

2 回答 2

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 不起作用,因为它“混合”了不同列中的最小值。

一个不错的方法可能是将子选择提取到它们自己的视图中,例如。EarliestContractPerPob 和LatestContractPerPob。

于 2019-10-04T09:31:35.723 回答
0

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

前提是我们已经根据与您的非常相似的表格按材料类型 ( MTART ) 数据集预先选择:mara

------------------------------------------------
|        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 |
------------------------------------------------

以下是材料,我们只想在创建日期 ( ERSDA ) 之前留下最后一个和第一个材料 ( MATNR ),并为第一个和最后一个找到维护类型 ( VPSTA )。

------------------------------------------------
|        MATNR     |   ERSDA  |   VPSTA  |MTART|
------------------------------------------------
|       17000000007|18.06.2018|KEDBXCZ   |ZSHD |
|       17000000113|06.02.2019|V         |ZSHD |
------------------------------------------------

在您的情况下,您类似地根据datefrom标准( )在每个POBmtart)源和目标合同contract_id(最后一个和第一个)中搜索。vpstaersda

一个可以使用UNION子查询和两个选择来实现:

 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日期,第二个选择获取最小日期。

按类型和日期排序的结果集将有点像您要查找的内容(F = 第一个,L = 最后一个):

在此处输入图像描述

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

 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).

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

关于实施的几句话。在您的示例中,我看到您使用 AMDP 类,但后来您提到ORDERCDS 不支持该类。是的,CDS 和子查询不支持它们,但 AMDP 支持它们。

您应该区分两种类型的 AMDP 函数:AMDP 方法的函数和 CDS 表函数的函数。第一个完美地处理带有排序和子查询的 SELECT。您可以在CL_DEMO_AMDP_VS_OPEN_SQL演示类中查看演示 AMDP 功能(包括子查询)的示例。您可以在 AMDP 函数中派生代码并从 CDS 表函数实现中调用它。

于 2019-10-27T01:41:35.787 回答