将相关的子查询替换为join

时间:2018-09-13 17:21:46

标签: greatest-n-per-group abap relational-algebra opensql cds

我想用等效联接替换下面的ABAP OpenSQL代码段(在更大的语句的where子句中)。

... AND tf~tarifart = ( SELECT MAX( tf2~tarifart ) FROM ertfnd AS tf2 WHERE tf2~tariftyp = e1~tariftyp AND tf2~bis >= e1~bis AND tf2~ab <= e1~ab ) ...

我的动机:查询迁移到ABAP CDS视图(基本上是纯SQL,相比之下表达性有所降低)。 las,不支持相关子查询和EXISTS语句。

我在Google上搜索了一下,并在https://archive.sap.com/discussions/thread/3824523

处找到了可能的解决方案(最新文章)

但是,提案

  
      
  1. 选择MAX(值)
  2.   
  3. 您的方案使用内部联接到第一个CDS视图
  4.   

在我的情况下不起作用。

    tli.tf.bis(和tf.ab)必须位于新视图的选择列表中,以将联接(新视图)的rhs限制在正确的时间范围内。 li,可能会有多个(不重叠)子时间帧(包含在[tf.ab,tf.bis]中),并且具有相同的tf.tarifart。 由于无法将这些分组在一起,因此会在rhs上导致多行。

原始查询对此没有问题(无联接->无笛卡尔积)。

我希望下面的小提琴(有效的例子)能使事情变得清晰:http://sqlfiddle.com/#!9/8d1f48/3

鉴于这些限制,在我看来,等效联接确实是不可能的。建议甚至确认?

1 个答案:

答案 0 :(得分:0)

select doc_belzart,
       doc_tariftyp,
       doc_ab,
       doc_bis,
       max(tar_tarifart)
  from 
  (
    select document.belzart as doc_belzart, 
           document.tariftyp as doc_tariftyp,  
           document.ab as doc_ab,
           document.bis as doc_bis, 
           tariff.tarifart as tar_tarifart,
           tariff.tariftyp as tar_tariftyp,
           tariff.ab as tar_ab,
           tariff.bis as tar_bis
      from dberchz1 as document
      inner join ertfnd as tariff
        on tariff.tariftyp = document.tariftyp and
           tariff.ab <= document.ab and
           tariff.bis >= document.bis
  ) as max_tariff
  group by doc_belzart,
          doc_tariftyp,
          doc_ab,
          doc_bis

用英语翻译,您似乎想确定一组文档的最高适用关税。

我将其重构为单独的步骤:

  1. 确定所有适用费率,即完全覆盖文档时间间隔的所有费率。这将成为您的第一个CDS视图,并在我的回答中形成子查询。

  2. 确定所有文档的最大适用关税。这将形成您的第二个CDS视图,在我的回答中将形成外部查询。该文件具有MAX / GROUP BY可以将每个文档的结果集减少为一个。