【问题标题】:Greatest N per group in Open SQLOpen SQL 中每组的最大 N
【发布时间】:2014-05-09 09:21:18
【问题描述】:

通过(部分)键从表中选择特定列中具有最大值的行是 SQL 中的常见任务。 This question 有一些很好的答案,涵盖了各种方法。不幸的是,我正在努力在我的 ABAP 程序中复制这一点。

似乎不支持常用的方法:

  • 加入子查询是not supported in syntax:SELECT * FROM X as x INNER JOIN ( SELECT ... ) AS y
  • 据我所知,语法不支持将 IN 用于复合键:SELECT * FROM X WHERE (key1, key2) IN ( SELECT key1 key2 FROM ... )
  • 不支持使用小于比较的左连接自身,外连接仅支持 EQ 比较:SELECT * FROM X AS x LEFT JOIN X as xmax ON x-key1 = xmax-key1 AND x-key2 < xmax-key2 WHERE xmax-key IS INITIAL

在依次尝试了这些解决方案中的每一个之后,却发现 ABAP 似乎不支持它们并且无法找到任何等价物,我开始认为我别无选择,只能转储itab 的子查询。

在 ABAP 开发中这种常见的编程要求的最佳实践是什么?

【问题讨论】:

  • 您有可以使用的密钥第一部分的参考表吗?
  • @vwegert 你的意思是我应该将复合键封装在一个结构中吗?我只见过被称为用于澄清价值列上的货币的参考表。

标签: greatest-n-per-group abap opensql


【解决方案1】:

首先,具体的要求,会给你一个更好的答案。因为它发生在一个程序中工作时,使用3种不同的方法伪分组,(而寻找替代品)和ALL 3可以用来回答你的问题,这依赖于你需要做什么,我碰到了这个问题。我敢肯定,有更多的方式来做到这一点。

例如,你可以在组内通过简单的选择MAX(your_field)以及某些字段分组拉最大值,如果这就是你所需要的。 P>

select bname, nation, max( date_from ) from adrp group by bname, nation. "selects highest "from" date for each bname

如果您需要使用的最大值作为过滤条件的查询中,你可以通过执行做伪分组使用这样的子查询(注意我是如何搬出BNAME内的子查询和max检查到的子查询,这意味着我没有检查使用in (subquery)加成)这两个字段:

select ... from adrp as b_adrp "Pulls the latest person info for a user (some conditions are missing, but this is a part of an actual query)
where b_adrp~date_from in (
    select max( date_from ) "Highest date_from where both dates are valid
         from adrp  where persnumber = b_adrp~persnumber and nation = b_adrp~nation and date_from <= @sy-datum )

上面的查询允许用户选择选择从基本查询的所有用户信息和(其中,第一个只允许采取聚集和分组数据)。 P>

最后,如果你需要基于复合材料重点检查,并将其与多个agregate功能的结果,实施将在很大程度上取决于你的需求细节(既然你的问题现在没有,我会提供一个通用的一个)。最简单的方法是使用exists / not exists代替in (subquery),以完全相同的方式,并形成子查询检查特定的按键或条件,而不是拉列表的所有脑干(你可以嵌套子查询,如果你有) :

 select * from bkpf where exists ( select 1 from bkpf as b where belnr = bkpf~belnr and gjahr = bkpf~gjahr group by belnr, gjahr having max( budat ) = bkpf~budat ) "Took an available example, that I had in testing program.

3个的所有查询,将让你列的最大值组内,事实上,所有3个可以使用连接来达到相同的结果。 P>

【讨论】:

    【解决方案2】:

    请在您的问题下方找到我的答案。

    • 语法不支持加入子查询:SELECT * FROM X as x INNER JOIN ( SELECT ... ) AS y

      将子查询放在您的 where 条件中应该可以完成工作 SELECT * FROM X AS x INNER JOIN Y AS y ON x~a = y~b WHERE ( SELECT * FROM y WHERE ... )

    • 据我所知,语法不支持将 IN 用于复合键:SELECT * FROM X WHERE (key1, key2) IN ( SELECT key1 key2 FROM ... )

      你必须拆分你的 WHERE 子句:SELECT * FROM X WHERE key1 IN ( SELECT key1 FROM y ) AND key2 IN ( SELECT key2 FROM y )

    • 不支持使用小于比较的左连接自身,外连接仅支持 EQ 比较。

      是的,目前就是这样。

    【讨论】:

      【解决方案3】:

      不支持以小于比较的方式与自身进行左连接,外连接仅支持 EQ 比较:

      SELECT * FROM X AS x LEFT JOIN X as xmax ON x-key1 = xmax-key1 AND x-key2

      这不是真的。此 SELECT 完全有效:

      SELECT b1~budat
        INTO TABLE lt_bkpf
        FROM bkpf AS b1
        LEFT JOIN bkpf AS b2
          ON b2~belnr < b1~belnr
       WHERE b1~bukrs <> ''.
      

      并且至少从 7.40 SP08 开始有效,因为 July 2013,所以在你问这个问题的时候它也是有效的。

      【讨论】:

        猜你喜欢
        • 2023-04-08
        • 2015-05-18
        • 2022-01-06
        • 2013-04-16
        • 2017-03-02
        • 1970-01-01
        • 2013-05-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多