OpenSQL 中的 WHERE 变量 = ( 子查询 )

Posted

技术标签:

【中文标题】OpenSQL 中的 WHERE 变量 = ( 子查询 )【英文标题】:WHERE variable = ( subquery ) in OpenSQL 【发布时间】:2015-02-19 08:37:16 【问题描述】:

我正在尝试从子查询与变量匹配的表中检索行。但是,似乎 WHERE 子句只允许我将所选表的字段与常量、变量或子查询进行比较。

我希望写这样的东西:

DATA(lv_expected_lines) = 5.
SELECT partner contract_account
INTO TABLE lt_bp_ca
FROM table1 AS tab1
WHERE lv_expected_lines = (
    SELECT COUNT(*)
    FROM table2
    WHERE partner          = tab1~partner
    AND   contract_account = tab1~contract_account ).

但显然,这个选择将我的局部变量视为字段名称,它给了我错误“未知列名“lv_expected_lines”,直到运行时,你不能指定一个字段列表。”

但在标准 SQL 中这是完全可能的:

SELECT PARTNER, CONTRACT_ACCOUNT
FROM TABLE1 AS TAB1
WHERE 5 = (
    SELECT COUNT(*)
    FROM TABLE2
    WHERE PARTNER          = TAB1.PARTNER
    AND   CONTRACT_ACCOUNT = TAB1.CONTRACT_ACCOUNT );

那么我怎样才能在 RSQL / Open SQL 中复制这个逻辑呢?

如果没有办法,我可能只会编写原生 SQL 并完成它。

【问题讨论】:

好问题。坦率地说,我从未见过这样的查询,其中 WHERE 条件的左侧在 OpenSQL 或标准 SQL 中都是常量。我认为这在 OpenSQL 中是不可能的,但是有可能以不同的方式编写查询并获得相同的结果。在 ABAP 中使用本机 SQL 绝不是一个好的选择。让我考虑一下... 【参考方案1】:

下面的程序可能会引导您使用 Open SQL 解决方案。它使用 SAP 演示表来确定在特定数量的航班上使用的飞机类型。

REPORT zgertest_sub_query.

DATA: lt_planetypes TYPE STANDARD TABLE OF s_planetpp.

PARAMETERS: p_numf TYPE i DEFAULT 62.

START-OF-SELECTION.

  SELECT planetype
         INTO TABLE lt_planetypes
         FROM  sflight
       GROUP BY planetype
       HAVING COUNT( * ) EQ p_numf.

  LOOP AT lt_planetypes INTO DATA(planetype).
    WRITE: / planetype.
  ENDLOOP.

仅当您不需要从 TAB1 读取字段时才有效。如果你这样做,你将不得不在循环结果时将这些与其他选择一起收集。

【讨论】:

这可以在大多数情况下工作,但不是全部,+1。我考虑过使用GROUP BY 的解决方案,但问题是,当场景包括表A 中的对象且表B 中有0 个条目时,这种方法效果不佳。例如,在SFLIGHT 中获取少于3 个平面的所有平面类型变为更加困难。在我的情况下,我认为这会导致选择性能低于标准,而在 ABAP 中编码逻辑会更快。【参考方案2】:

对于那些在 2020 年发现这个问题的人,我报告说,自 ABAP 7.50 起就支持这种结构。无需解决方法:

SELECT kunnr, vkorg
FROM vbak AS v
WHERE 5 = ( SELECT COUNT(*)
              FROM vbap
             WHERE kunnr = v~kunnr
               AND vkorg = v~vkorg )
 INTO TABLE @DATA(customers).

这会选择在某个销售组织内下达 5 个销售订单的所有客户。

【讨论】:

【参考方案3】:

在 ABAP 中,无法像在 NATIVE SQL 中那样进行查询。 我建议不要使用 NATIVE SQL,而是尝试 SELECT/ENDSELECT 语句。

DATA: ls_table1 type table1,
      lt_table1 type table of table1,
      lv_count  type i.

SELECT PARTNER, CONTRACT_ACCOUNT
INTO ls_table1
FROM TABLE1.

      SELECT COUNT(*)
        INTO lv_count
        FROM TABLE2
       WHERE PARTNER          = TAB1.PARTNER
        AND  CONTRACT_ACCOUNT = TAB1.CONTRACT_ACCOUNT.

  CHECK lv_count EQ 5.
  APPEND ls_table1 TO lt_table1.

ENDSELECT

在这里,您仅将在选择 table2 时计数等于 5 的那些行附加到 ls_table1。

希望对你有帮助。

【讨论】:

以上是关于OpenSQL 中的 WHERE 变量 = ( 子查询 )的主要内容,如果未能解决你的问题,请参考以下文章

如何修复 Laravel 5.2 中的“未定义变量:子任务”

如何将子查询的值存储到 Hana Studio 中的变量中?

SAP abap 怎么拆分字符串?

where条件放在子SQL语句中是否查询速度更快?

SQL 中 where 后面可不可以跟上子查询

from 子查询在 where 语句中的重用