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 中的“未定义变量:子任务”