Вот пример концепции решения вашей задачи.
При условии, что мы предварительно выбрали набор данных типа материала ( 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 |
------------------------------------------------
Вот материалы, и мы хотим оставить только последний и первый материал ( MATNR ) по дате создания ( 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 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 = последний):
![enter image description here](https://i.stack.imgur.com/hRetd.png)
Ваш 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, но позже вы упомянули, что ORDER
не поддерживается CDS. Да, они не поддерживаются в CDS, а также в подзапросах, но они поддерживаются в AMDP.
Следует различать два типа функций AMDP : функции для метода AMDP и функции дляТабличные функции CDS. Первые отлично обрабатывают SELECT с сортировкой и подзапросами. Вы можете просмотреть примеры в демонстрационном классе CL_DEMO_AMDP_VS_OPEN_SQL
, который демонстрирует функции AMDP, включая подзапросы. Вы можете получить свой код в функции AMDP и вызвать его из реализации табличной функции CDS.