Вот доказательство концепции решения вашей задачи.
При условии, что у нас есть предварительно выбранный по типу материала (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). strong>) для первого и последнего.
------------------------------------------------
| 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 = последний):
![введите здесь описание изображения](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.
person
Suncatcher
schedule
27.10.2019