每组数据集中的极值
Extreme values within each group of dataset
我有一个用 AMDP 编写的 SQLScript 查询,它创建了两个新列 source_contract
和 target_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 中不可用。
您已经有了子选择的最优解。
伪代码:
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 不起作用,因为它"mixes up" 不同列中的最小值。
一个很好的方法可能是将子选择提取到它们自己的视图中,例如。 EarliestContractPerPob 和 LatestContractPerPob。
这是您任务的概念验证解决方案。
前提是我们已经预先select编辑了material类型的(MTART)基于tablemara
的数据集和你的很像:
------------------------------------------------
| 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 |
------------------------------------------------
这是 materials,我们只想在创建日期(ERSDA) 并找到第一个和最后一个的维护类型 (VPSTA)。
------------------------------------------------
| MATNR | ERSDA | VPSTA |MTART|
------------------------------------------------
| 17000000007|18.06.2018|KEDBXCZ |ZSHD |
| 17000000113|06.02.2019|V |ZSHD |
------------------------------------------------
在您的情况下,您类似地在每个 POB (mtart
) 源和目标合同中搜索 contract_id (最后和第一个 vpsta
) 基于 datefrom 标准 (ersda
).
可以使用 UNION
和两个带有子查询的 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).
在这里您可以注意到第一个 select 获取最大 ersda
日期,第二个 select 获取最小日期。
按类型和日期排序的结果集在某种程度上就是您要查找的内容(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
日期时有效,否则查询将不知道您要使用哪个 last/first 合同。此外,如果每个 POB 中只有一个合同,则只有一个记录。
关于实施的几句话。在您的示例中,我看到您使用了 AMDP class,但后来您提到 CDS 不支持 ORDER
。是的,CDS 和子查询不支持它们,但 AMDP 支持它们。
您应该区分 two types of AMDP functions:AMDP 方法的函数和 CDS table 函数的函数。第一个完美地处理 SELECTs 排序和子查询。您可以在 CL_DEMO_AMDP_VS_OPEN_SQL
演示 class 中查看示例,其中演示了包括子查询在内的 AMDP 功能。您可以在 AMDP 函数中派生代码并从 CDS table 函数实现中调用它。
我有一个用 AMDP 编写的 SQLScript 查询,它创建了两个新列 source_contract
和 target_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 中不可用。
您已经有了子选择的最优解。
伪代码:
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 不起作用,因为它"mixes up" 不同列中的最小值。
一个很好的方法可能是将子选择提取到它们自己的视图中,例如。 EarliestContractPerPob 和 LatestContractPerPob。
这是您任务的概念验证解决方案。
前提是我们已经预先select编辑了material类型的(MTART)基于tablemara
的数据集和你的很像:
------------------------------------------------
| 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 |
------------------------------------------------
这是 materials,我们只想在创建日期(ERSDA) 并找到第一个和最后一个的维护类型 (VPSTA)。
------------------------------------------------
| MATNR | ERSDA | VPSTA |MTART|
------------------------------------------------
| 17000000007|18.06.2018|KEDBXCZ |ZSHD |
| 17000000113|06.02.2019|V |ZSHD |
------------------------------------------------
在您的情况下,您类似地在每个 POB (mtart
) 源和目标合同中搜索 contract_id (最后和第一个 vpsta
) 基于 datefrom 标准 (ersda
).
可以使用 UNION
和两个带有子查询的 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).
在这里您可以注意到第一个 select 获取最大 ersda
日期,第二个 select 获取最小日期。
按类型和日期排序的结果集在某种程度上就是您要查找的内容(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
日期时有效,否则查询将不知道您要使用哪个 last/first 合同。此外,如果每个 POB 中只有一个合同,则只有一个记录。
关于实施的几句话。在您的示例中,我看到您使用了 AMDP class,但后来您提到 CDS 不支持 ORDER
。是的,CDS 和子查询不支持它们,但 AMDP 支持它们。
您应该区分 two types of AMDP functions:AMDP 方法的函数和 CDS table 函数的函数。第一个完美地处理 SELECTs 排序和子查询。您可以在 CL_DEMO_AMDP_VS_OPEN_SQL
演示 class 中查看示例,其中演示了包括子查询在内的 AMDP 功能。您可以在 AMDP 函数中派生代码并从 CDS table 函数实现中调用它。