5

我想对具有 6 个关键字段的数据库表执行 SELECT 查询,假设它们是 keyA、keyB、...、keyF。

作为我的 ABAP 功能模块的输入参数,我确实收到了一个内部表,该表具有与关键字段完全相同的结构,因此该内部表中的每个条目对应于数据库表中的一个元组。

因此,我只需要从数据库表中选择与我的内部表中的条目相对应的所有元组。此外,我想在完全相同的查询中聚合该数据库表中的金额列。

在伪 SQL 中,查询如下所示:SELECT SUM(amount) FROM table WHERE (keyA, keyB, keyC, keyD, keyE, keyF) IN {internal table}。

但是,这种表示在 ABAP OpenSQL 中是不可能的。

只允许声明一列(例如 keyA),而不是复合键。此外,我只能在关键字 IN 之后使用“选择表”(带有 SIGN、OPTIOn、LOW、HIGH 的那些)。使用 FOR ALL ENTRIES 似乎是可行的,但是在这种情况下,我不能使用 SUM,因为在同一个查询中不允许聚合。

有什么建议么?

4

3 回答 3

3

对于为内部表的每个条目选择记录,通常for all entriesABAP Open SQL 中的习语是您的朋友。在您的情况下,您有额外的要求来汇总总和。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.
于 2015-04-15T10:07:33.223 回答
2

我会用它FOR ALL ENTRIES来获取所有相关的行,然后LOOP对结果表进行四舍五入并将相关字段加起来。如果您有 ABAP 740 或更高版本,则可以使用REDUCEoperator 来避免手动循环表格:

DATA(total) = REDUCE i( INIT sum = 0
                        FOR wa IN itab NEXT sum = sum + wa-field ).
于 2015-04-15T10:21:34.617 回答
0

一种可能的方法是使用语句语句在 SELECT 循环内同时汇总SELECT...ENDSELECT

计算工厂所有订单行/数量的示例:

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是上述材料选择的数量总计,最后一个查询是最终的输出查询。

于 2020-03-20T13:27:59.137 回答