我需要提取存档表中没有历史记录的记录。 2 需要在存档中检查 1 条记录的字段。
从技术意义上讲,我的要求是左连接,其中右侧为"null"(又名排除连接(,在 abap openSQL 中通常这样实现(无论如何对于我的场景(:
Select * from xxxx //xxxx is a result for a multiple table join
where xxxx~key not in (select key from archive_table where [conditions] )
and xxxx~foreign_key not in (select key from archive_table where [conditions] )
这 2 个字段还会针对另外 2 个表进行检查,因此这意味着总共有 6 个子查询。
我以前使用过的数据库引擎通常有一些方法来处理此类问题(例如排除 join 或外部应用(。
对于这种特殊情况,我将尝试将 ABAP 逻辑与"对于所有条目"一起使用,但我仍然想知道是否可以使用子查询的结果来检查超过 1 个字段或使用另一种形式排除多个字段的连接逻辑使用SQL(不涉及应用程序服务器(。
我已经在我制作的程序的生命周期中测试了相当多的子查询变体。 在某些情况下,具有多个字段检查(下面的缩短示例(以排除基于2个键的NOT EXISTS
有效。 性能可以接受(处理时间约为 5 秒(,但在基于 1 个字段排除时,它明显比同一查询慢。
Select * from xxxx //xxxx is a result for a multiple table inner joins and 1 left join ( 1-* relation )
where NOT EXISTS (
select key from archive_table
where key = xxxx~key OR key = XXXX-foreign_key
)
编辑:随着需求的变化(更多过滤(,很多东西都发生了变化,所以我想我会更新这个。我在示例中标记为XXXX
的结构包含一个左连接(其中主表与辅助表的关系1-*
(,并且看起来相对较快。
这就是上下文有助于理解问题的地方:
- 初始要求:拉
vendors
全部,无财务记录3 表。 - 附加要求:也可根据替代方案排除
payers
(1-*
关系(。这就是上面的例子所基于的。 - 更多要求:也排除基于替代
payee
(*-*
payer
和payee
之间的关系(。
多对多连接呈指数级增长,我标记为XXXX
的结构中的记录计数,这反过来又产生了许多不必要的工作。例如:一个客户有 3 个payers
和 3 个payees
生成了 9 行,总共有 27 个字段需要检查(每行 3 个(,而实际上只有 7 个唯一值。
此时,将左联接的表从主查询移动到子查询并拆分它们可以显著提高性能。 比任何看起来更聪明的替代品。
select * from lfa1 inner join lfb1
where
( lfa1~lifnr not in ( select lifnr from bsik where bsik~lifnr = lfa1~lifnr )
and lfa1~lifnr not in ( select wyt3~lifnr from wyt3 inner join t024e on wyt3~ekorg = t024e~ekorg and wyt3~lifnr <> wyt3~lifn2
inner join bsik on bsik~lifnr = wyt3~lifn2 where wyt3~lifnr = lfa1~lifnr and t024e~bukrs = lfb1~bukrs )
and lfa1~lifnr not in ( select lfza~lifnr from lfza inner join bsik on bsik~lifnr = lfza~empfk where lfza~lifnr = lfa1~lifnr )
)
and [3 more sets of sub queries like the 3 above, just checking different tables].
我的结论:
- 当排除基于单个字段时,
not in
/not exits
都有效。一个可能比另一个更好,具体取决于您使用的过滤器。 - 当排除基于 2 个或更多字段,并且主查询中没有多对多联接时,
not exists ( select .. from table where id = a.id or id = b.id or... )
似乎是最好的。 - 当您的排除条件在主查询中实现多对多关系时,我建议您寻找一种实现多个子查询的最佳方法(即使为每个键表组合都有一个子查询也会比具有 1 个良好子查询的多对多联接性能更好,这看起来不错(。
无论如何,欢迎对此有任何额外的见解。
EDIT2:虽然有点偏离主题,但考虑到我关于子查询的问题,我想我会发布更新。一年多后,我不得不重新审视我致力于扩展它的解决方案。我了解到正确排除加入是有效的。我只是在第一次实施它时失败了。
select header~key
from headers left join items on headers~key = items~key
where items~key is null
使用子查询的结果来检查超过 超过 1 个字段或使用另一种形式排除多个联接逻辑 领域
不,无法在子查询中检查两列,因为 SAP 帮助明确指出:
子查询subquery_clauses中的子句必须构成标量子查询。
标量在这里是关键字,即它应该只返回一列。
您的子查询可以具有多列键,并且这样的语法是完全合法的:
SELECT planetype, seatsmax
FROM saplane AS plane
WHERE seatsmax < @wa-seatsmax AND
seatsmax >= ALL ( SELECT seatsocc
FROM sflight
WHERE carrid = @wa-carrid AND
connid = @wa-connid )
但是您说这两个字段应该针对不同的表进行检查
这两个字段还针对另外两个表进行检查
所以你不是这种情况。您唯一的选择似乎是多重联接。
附言FOR ALL ENTRIES
不支持否定逻辑,你不能只使用某种NOT IN FOR ALL ENTRIES
,这不会那么容易。