首页 文章

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

提问于
浏览
2

我需要提取记录,这些记录在归档表中没有历史记录 . 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 回答

  • 1

    我在我正在制作的程序的生命周期中测试了很多子查询 . NOT EXISTS 具有多个字段检查(下面的简短示例),基于2个键排除在某些情况下有效 . 性能可接受(处理时间约为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表中没有财务记录 .

    • 附加要求:也基于备选 payers1-* 关系)排除 . 这就是上面的例子 .

    • 更多要求:也基于备选 payeepayerpayee 之间的 *-* 关系)排除 .

    多对多连接以指数方式增加了我标记为 XXXX 的构造中的记录数,这反过来又产生了许多不必要的工作 . 例如:单个客户3 payers 和3 payees 产生9行,共有27个字段要检查(每行3个),而实际上只有7个唯一值 .

    此时,将左连接表从主查询移动到子查询 and splitting them 可以显着提高性能 . 比任何更聪明的替代品 .

    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].
    

    My Conclusion

    • 当排除基于单个字段时, not in / not exits 都有效 . 一个可能比另一个好,这取决于您使用的过滤器 .

    • 当排除基于2个或更多字段且您在主查询中没有多对多连接时, not exists ( select .. from table where id = a.id or id = b.id or... ) 似乎是最佳的 .

    • 当您的排除标准在主查询中实现多对多关系时,我建议寻找实现多个子查询的最佳方式(即使每个键表组合的子查询也会表现更好而不是多对多加入一个好的子查询,看起来不错) .

    无论如何,对此的任何其他见解都是受欢迎的 .

  • 0

    如果可以使用子查询的结果来检查多于1个字段,或者在多个字段中使用另一种形式的排除连接逻辑

    不,不可能在子查询中检查两列,因为SAP Help清楚地说:

    子查询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     )
    

    但是你说应该针对不同的表检查这两个字段

    还会针对另外两个表检查这两个字段

    所以情况并非如此 . 您唯一的选择似乎是多连接 .

    P.S. FOR ALL ENTRIES 不支持否定逻辑,你不能只使用某种NOT IN FOR ALL ENTRIES,它就不那么容易了 .

相关问题