我想对一个有6个键字段的数据库表执行SELECT查询,假设它们是keyA、keyB。。。,键F。
作为ABAP功能模块的输入参数,我确实收到了一个内部表,该表具有完全相同的键字段结构,因此该内部表中的每个条目对应于数据库表中的一个元组。
因此,我只需要从数据库表中选择与内部表中的条目相对应的所有元组。此外,我希望在完全相同的查询中聚合该数据库表中的amount列。
在伪SQL中,查询将如下所示:SELECT SUM(amount)FROM表WHERE(keyA,keyB,keyC,keyD,keyE,keyF)IN{internal table}。
但是,这种表示在ABAP OpenSQL中是不可能的。
只允许声明一列(如keyA),而不允许声明复合键。此外,我只能在关键字IN之后使用"选择表"(带有SIGN、OPTIOn、LOW、HIGH的表)。使用FOR ALL ENTRIES似乎是可行的,但在这种情况下,我不能使用SUM,因为在同一查询中不允许聚合。
有什么建议吗?
对于为内部表的每个条目选择记录,ABAP Open SQL中的for all entries
习惯用法通常是您的朋友。在您的情况下,您有额外的要求来合计一笔金额。不幸的是,使用for all entries
的SELECT语句的结果集不允许使用聚合函数。在我看来,这种情况下最好的方法是根据ABAP层中的结果集计算和。以下示例适用于我的系统(顺便注意:使用7.40附带的新ABAP语言功能,可以大大缩短整个代码)。
report zz_ztmp_test.
start-of-selection.
perform test.
* Database table ZTMP_TEST :
* ID - key field - type CHAR10
* VALUE - no key field - type INT4
* Content: 'A' 10, 'B' 20, 'C' 30, 'D' 40, 'E' 50
types: ty_entries type standard table of ztmp_test.
* ---
form test.
data: lv_sum type i,
lt_result type ty_entries,
lt_keys type ty_entries.
perform fill_keys changing lt_keys.
if lt_keys is not initial.
select * into table lt_result
from ztmp_test
for all entries in lt_keys
where id = lt_keys-id.
endif.
perform get_sum using lt_result
changing lv_sum.
write: / lv_sum.
endform.
form fill_keys changing ct_keys type ty_entries.
append :
'A' to ct_keys,
'C' to ct_keys,
'E' to ct_keys.
endform.
form get_sum using it_entries type ty_entries
changing value(ev_sum) type i.
field-symbols: <ls_test> type ztmp_test.
clear ev_sum.
loop at it_entries assigning <ls_test>.
add <ls_test>-value to ev_sum.
endloop.
endform.
我会使用FOR ALL ENTRIES
来获取所有相关的行,然后LOOP
对结果表进行取整,并将相关字段相加为总数。如果您有ABAP740或更高版本,您可以使用REDUCE
运算符来避免手动循环表:
DATA(total) = REDUCE i( INIT sum = 0
FOR wa IN itab NEXT sum = sum + wa-field ).
一种可能的方法是使用语句SELECT...ENDSELECT
在SELECT循环内同时进行汇总。
计算工厂所有订单行/数量的样本:
TYPES: BEGIN OF ls_collect,
werks TYPE t001w-werks,
menge TYPE ekpo-menge,
END OF ls_collect.
DATA: lt_collect TYPE TABLE OF ls_collect.
SELECT werks UP TO 100 ROWS
FROM t001w
INTO TABLE @DATA(lt_werks).
SELECT werks, menge
FROM ekpo
INTO @DATA(order)
FOR ALL ENTRIES IN @lt_werks
WHERE werks = @lt_werks-werks.
COLLECT order INTO lt_collect.
ENDSELECT.
这个样品没有商业意义,放在这里只是为了教育目的。
另一种更健壮和现代的方法是自ABAP751版本以来可用的CTE(通用表表达式)。此技术特别适用于总计/小计任务:
WITH
+plants AS (
SELECT werks UP TO 100 ROWS
FROM t011w ),
+orders_by_plant AS (
SELECT SUM( menge )
FROM ekpo AS e
INNER JOIN +plants AS m
ON e~werks = m~werks
GROUP BY werks )
SELECT werks, menge
FROM +orders_by_plant
INTO TABLE @DATA(lt_sums)
ORDER BY werks.
cl_demo_output=>display( lt_sums ).
第一个表表达式+material
是您的内部表,第二个+orders_by_mat
是由上述材料选择的数量总和,最后一个查询是最终输出查询。