我想在具有6个关键字段的数据库表上执行SELECT查询,假设它们是keyA,keyB,...,keyF。
作为我的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,因为在同一个查询中不允许聚合。
有什么建议吗?
答案 0 :(得分:3)
为了选择内部表的每个条目的记录,通常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.
答案 1 :(得分:2)
我会使用FOR ALL ENTRIES
来获取所有相关的行,然后LOOP
围绕结果表并将相关字段添加到总计中。如果你有ABAP 740或更高版本,你可以使用REDUCE
运算符来避免必须手动循环遍历表:
DATA(total) = REDUCE i( INIT sum = 0
FOR wa IN itab NEXT sum = sum + wa-field ).
答案 2 :(得分:0)
一种可能的方法是使用语句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.
该样本没有商业意义,仅出于教育目的而放置在此处。
从ABAP 751版本开始,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
数量总计,最后一个查询是最终输出查询。