选择多个字段不在子查询中的位置(不包括连接)



我需要提取存档表中没有历史记录的记录。 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(*-*payerpayee之间的关系(。

多对多连接呈指数级增长,我标记为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,这不会那么容易。

相关内容

  • 没有找到相关文章

最新更新