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:
------------------------------------------------
| 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.
------------------------------------------------
| 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
).
One can achieve that using UNION
and two selects with sub-queries:
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.
The resulted set ordered by type and date will be somewhat what are you looking for (F = first, L = last):

Your SELECT should look somewhat like this:
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. Also, in case of the only one contract within each POB there will be only one record.
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. Yes, they are not supported in CDS as well as sub-queries, but they are supported in AMDP.
You should differentiate two types of AMDP functions: functions for AMDP method and functions for CDS table functions. The first ones perfectly handle SELECTs with sorting and sub-queries. You can view the samples in CL_DEMO_AMDP_VS_OPEN_SQL
demo class which demonstrate AMDP features including sub-queries. You can derive you code in AMDP function and call it from your CDS table function implementation.