我需要提取记录,这些记录在归档表中没有历史记录 . 2需要在存档中检查1条记录的字段 .
在技术意义上,我的要求是左连接,其中右边是'null'(a.k.a . 是一个排除连接),在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] )
还会针对另外两个表检查这两个字段,这意味着总共有6个子查询 .
我之前使用的数据库引擎通常有一些方法来处理这些问题(例如排除连接或外部应用) .
对于这种特殊情况,我将尝试使用ABAP逻辑'for all entries',但 I would still like to know if it is possible to use results of a sub-query to check more than than 1 field or use another form of excluding join logic on multiple fields 使用SQL(不涉及应用程序服务器) .
2 回答
我在我正在制作的程序的生命周期中测试了很多子查询 .
NOT EXISTS
具有多个字段检查(下面的简短示例),基于2个键排除在某些情况下有效 . 性能可接受(处理时间约为5秒),但是,基于1字段排除时,它明显慢于同一查询 .编辑:随着需求的变化(更多的过滤),很多都发生了变化,所以我想我会更新它 . 在我的示例中标记为
XXXX
的构造包含单个左连接(其中主要与次要表关系为1-*
)并且它看起来相对较快 .这是上下文有助于理解问题的地方:
初始要求:全部拉
vendors
,3表中没有财务记录 .附加要求:也基于备选
payers
(1-*
关系)排除 . 这就是上面的例子 .更多要求:也基于备选
payee
(payer
和payee
之间的*-*
关系)排除 .多对多连接以指数方式增加了我标记为
XXXX
的构造中的记录数,这反过来又产生了许多不必要的工作 . 例如:单个客户3payers
和3payees
产生9行,共有27个字段要检查(每行3个),而实际上只有7个唯一值 .此时,将左连接表从主查询移动到子查询 and splitting them 可以显着提高性能 . 比任何更聪明的替代品 .
My Conclusion :
当排除基于单个字段时,
not in
/not exits
都有效 . 一个可能比另一个好,这取决于您使用的过滤器 .当排除基于2个或更多字段且您在主查询中没有多对多连接时,
not exists ( select .. from table where id = a.id or id = b.id or... )
似乎是最佳的 .当您的排除标准在主查询中实现多对多关系时,我建议寻找实现多个子查询的最佳方式(即使每个键表组合的子查询也会表现更好而不是多对多加入一个好的子查询,看起来不错) .
无论如何,对此的任何其他见解都是受欢迎的 .
不,不可能在子查询中检查两列,因为SAP Help清楚地说:
标量是这里的关键字,即它应该只返回一列 .
您的子查询可以有多列键,这种语法完全合法:
但是你说应该针对不同的表检查这两个字段
所以情况并非如此 . 您唯一的选择似乎是多连接 .
P.S.
FOR ALL ENTRIES
不支持否定逻辑,你不能只使用某种NOT IN FOR ALL ENTRIES,它就不那么容易了 .