简体   繁体   English

每组数据集中的极值

[英]Extreme values within each group of dataset

I have an SQLScript query written in AMDP which creates two new columns source_contract and target_contract .我有一个用 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

Original data:原始数据:

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

Data from AMDP view: AMDP 视图中的数据: 在此处输入图像描述

I want to ignore any intermediate rows (Date is the criteria to decide order).我想忽略任何中间行(日期是决定顺序的标准)。 Any suggestion or ideas?有什么建议或想法吗?

I thought of using Group by to get the max date and min date and using union on these entries in a separate consumption view but if we are using group by we can't fetch other entries.我想过使用Group by来获取最大日期和最小日期,并在单独的消费视图中对这些条目使用联合,但是如果我们使用group by我们将无法获取其他条目。 The other possibility is order by date but it is not available in CDS.另一种可能性是按日期订购,但它在 CDS 中不可用。

You already have the optimal solution with sub-selects.您已经有了子选择的最佳解决方案。

Pseudo code:伪代码:

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 won't work as it "mixes up" the minimums in different columns. GROUP BY 不起作用,因为它“混合”了不同列中的最小值。

A nice touch might be extracting the sub-selects into views of their own, eg.一个不错的方法可能是将子选择提取到它们自己的视图中,例如。 EarliestContractPerPob and LatestContractPerPob. EarliestContractPerPob 和LatestContractPerPob。

Here is the proof-of-concept of solution for your task.这是您的任务的解决方案的概念验证。

Provided we have pre-selected by material type ( MTART ) dataset based on table mara which is quite similar to yours:前提是我们已经根据与您的非常相似的表mara按材料类型 ( MTART ) 数据集预先选择:

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

Here are the materials and we want to leave only the last and the first material ( MATNR ) by creation date ( ERSDA ) and find maintenance type ( VPSTA ) for first and last ones.以下是材料,我们只想在创建日期 ( ERSDA ) 之前留下最后一个和第一个材料 ( MATNR ),并为第一个和最后一个找到维护类型 ( VPSTA )。

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

In your case you similarly search within each POB ( mtart ) source and target contracts contract_id (last and first vpsta ) on the basis of datefrom criterion ( ersda ).在您的情况下,您类似地根据datefrom标准( ersda )在每个POBmtart )源和目标合同contract_id (最后一个和第一个vpsta )中搜索。

One can achieve that using UNION and two selects with sub-queries:可以使用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).

Here you can notice the first select fetches max ersda dates and the second select fetches min ones.在这里您可以注意到第一个 select 获取最大ersda日期,第二个 select 获取最小日期。

The resulted set ordered by type and date will be somewhat what are you looking for (F = first, L = last):按类型和日期排序的结果集将有点像您要查找的内容(F = 第一个,L = 最后一个):

在此处输入图像描述

Your SELECT should look somewhat like this:您的 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).

Note, this will work only if you have unique datefrom dates, otherwise the query will not know which last/first contract you want to use.请注意,这仅在您具有唯一datefrom日期时才有效,否则查询将不知道您要使用哪个最后/第一个合同。 Also, in case of the only one contract within each POB there will be only one record.此外,如果每个 POB 中只有一个合同,则只有一个记录。

A couple of words about implementation.关于实施的几句话。 In your sample I see that you use AMDP class but later you mentioned that ORDER is not supported by CDS.在您的示例中,我看到您使用 AMDP class 但后来您提到 CDS 不支持ORDER Yes, they are not supported in CDS as well as sub-queries, but they are supported in AMDP.是的,CDS 和子查询不支持它们,但 AMDP 支持它们。

You should differentiate two types of AMDP functions : functions for AMDP method and functions for CDS table functions.您应该区分两种类型的 AMDP 函数:AMDP 方法的函数和 CDS 表函数的函数。 The first ones perfectly handle SELECTs with sorting and sub-queries.第一个完美地处理带有排序和子查询的 SELECT。 You can view the samples in CL_DEMO_AMDP_VS_OPEN_SQL demo class which demonstrate AMDP features including sub-queries.您可以在CL_DEMO_AMDP_VS_OPEN_SQL演示 class 中查看示例,该示例演示了包括子查询在内的 AMDP 功能。 You can derive you code in AMDP function and call it from your CDS table function implementation.您可以在 AMDP function 中派生代码,并从您的 CDS 表 function 实现中调用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM