-
Notifications
You must be signed in to change notification settings - Fork 4
Агрегирующие функции в подзапросах ABAP SQL
OlegBash599 edited this page Jan 17, 2024
·
12 revisions
Пусть у нас есть следующая модель данных (прообраз сбытовых VBAK-VBAP-BUT000).
Структура таблицы ZSLS_ORD_H
Поле | Тип | Комментарий |
---|---|---|
ID_NUM | CHAR(10) | Номер заказа, Ключ |
PARTNER | CHAR(10) | ID-клиента |
NUM_EXT | CHAR(35) | Внешний номер заказа |
Структура таблицы ZSLS_ORD_I
Поле | Тип | Комментарий |
---|---|---|
ID_NUM | CHAR(10) | Номер заказа, Ключ |
ITEM_NUM | CHAR(10) | Номер позиции, Ключ |
PROD_ID | Номер продукта | |
PRICE | Цена | |
QUAN | Кол-во | |
UOM | Единица измерения |
Структура таблицы ZPARTNER_H
Поле | Тип | Комментарий |
---|---|---|
PARTNER | CHAR(10) | ID-клиента, Ключ |
PARTNER_NAME | CHAR(200) | Наименование клиента |
Таблицы заполнены с помощью метода ниже.
METHOD _prepare_tabs.
DATA lt_ord_h TYPE STANDARD TABLE OF zsls_ord_h.
DATA lt_ord_i TYPE STANDARD TABLE OF zsls_ord_i.
DATA lt_partner_h TYPE STANDARD TABLE OF zpartner_h.
lt_ord_h = VALUE #(
( id_num = '1001' partner = '2001' num_ext = 'EXT_NUM_FOR_1001' )
( id_num = '1002' partner = '2002' num_ext = 'EXT_NUM_FOR_1002' )
( id_num = '1003' partner = '2003' num_ext = 'EXT_NUM_FOR_1003' ) ).
lt_ord_i = VALUE #(
( id_num = '1001' item_num = '1' prod_id = 'PRODUCT_91' price = '20'
quan = 5 uom = 'PC' total = 100 waers = 'RUB' )
( id_num = '1001' item_num = '2' prod_id = 'PRODUCT_92' price = '25'
quan = 6 uom = 'PC' total = 150 waers = 'RUB' )
( id_num = '1001' item_num = '3' prod_id = 'PRODUCT_93' price = '15'
quan = 7 uom = 'PC' total = 105 waers = 'RUB' )
( id_num = '1002' item_num = '1' prod_id = 'PRODUCT_81' price = '20'
quan = 3 uom = 'PC' total = 60 waers = 'RUB' )
( id_num = '1002' item_num = '2' prod_id = 'PRODUCT_82' price = '30'
quan = 8 uom = 'PC' total = 240 waers = 'RUB' )
( id_num = '1002' item_num = '3' prod_id = 'PRODUCT_83' price = '40'
quan = 4 uom = 'PC' total = 120 waers = 'RUB' )
( id_num = '1003' item_num = '1' prod_id = 'PRODUCT_71' price = '33'
quan = 7 uom = 'PC' total = 231 waers = 'RUB' )
( id_num = '1003' item_num = '2' prod_id = 'PRODUCT_72' price = '23'
quan = 15 uom = 'PC' total = 345 waers = 'RUB' )
).
lt_partner_h = VALUE #(
( partner = '2001' partner_name = 'ООО Полезное оборудование' )
( partner = '2002' partner_name = 'ЗАО Тюльпанчик' )
( partner = '2003' partner_name = 'ПАО Простоцарский банк' )
).
MODIFY zsls_ord_h FROM TABLE lt_ord_h.
MODIFY zsls_ord_i FROM TABLE lt_ord_i.
MODIFY zpartner_h FROM TABLE lt_partner_h.
COMMIT WORK.
ENDMETHOD.
Нужно вывести список заказов с позицией с номер позиции с наибольшей суммой, наибольшую сумму, наименьшую сумму и наименование клиента.
Набор полей, которые требуется отобразить.
TYPES: BEGIN OF ts_res
, id_num TYPE zsls_ord_h-id_num
, item_num TYPE zsls_ord_i-item_num
, partner_name TYPE zpartner_h-partner_name
, total_max TYPE zsls_ord_i-total
, total_min TYPE zsls_ord_i-total
, END OF ts_res
, tt_res TYPE STANDARD TABLE OF ts_res WITH DEFAULT KEY
.
Решение этой задачи средствами ABAP SQL будет зависеть от версии система.
Версия ABAP до 752.
До версии 752 у нас есть возможность в подзапросах использовать скалярные значения других запросов. В данном случае в подзапросе вычислим максимальное и минимальное значения и укажем их в условии WHERE.[Доступно с версии 4.7](https://help.sap.com/saphelp_470/helpdata/EN/fc/eb39c4358411d1829f0000e829fbfe/frameset.htm)
DATA lt_res TYPE tt_res.
" доступно с 4.7
" https://help.sap.com/saphelp_470/helpdata/EN/fc/eb39c4358411d1829f0000e829fbfe/frameset.htm
" в подзапросе возвращается скалярное выражение и
" и его используем как значение для общего JOIN
SELECT h~id_num imax~item_num k~partner_name imax~total as total_max imin~total as total_min
FROM zsls_ord_i AS imax JOIN zsls_ord_h AS h ON imax~id_num EQ h~id_num
join zsls_ord_i AS imin ON imin~id_num EQ imax~id_num
JOIN zpartner_h AS k ON h~partner EQ k~partner
INTO TABLE lt_res
WHERE
imax~total EQ (
SELECT MAX( total ) FROM zsls_ord_i WHERE id_num EQ h~id_num
)
and
imin~total EQ (
SELECT MIN( total ) FROM zsls_ord_i WHERE id_num EQ h~id_num
)
ORDER BY h~id_num imax~item_num
.
Версия 752 и выше (доступны Common Table Expressions).
" Используем CTE для формирования подзапросов
" https://help.sap.com/doc/abapdocu_752_index_htm/7.52/en-US/index.htm?file=abapwith_subquery.htm
WITH +ord_item_subtot AS (
SELECT h~id_num AS ord_num, MAX( i~total ) AS maxtotal_item, MIN( i~total ) AS mintotal_item
FROM zsls_ord_h AS h JOIN zsls_ord_i AS i ON h~id_num EQ i~id_num
GROUP BY h~id_num
)
SELECT h~id_num, i~item_num, k~partner_name, subtot~maxtotal_item, subtot~mintotal_item
FROM zsls_ord_i AS i JOIN zsls_ord_h AS h
ON i~id_num EQ h~id_num
JOIN +ord_item_subtot AS subtot ON i~id_num EQ subtot~ord_num and i~total = subtot~maxtotal_item
JOIN zpartner_h AS k ON h~partner EQ k~partner
ORDER BY h~id_num
INTO TABLE @lt_res
.
В качестве результата получим таким значения в данном случае.