Open SQL中每个组的最大N



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

似乎不支持常用的方法:

  • 语法不支持子查询的连接: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开发中,这种常见编程需求的最佳实践是什么?

首先,具体的要求,会给你一个更好的答案。碰巧的是,我在编写一个程序时遇到了这个问题,该程序使用3种不同的伪分组方法(同时寻找替代方法),并且所有3种方法都可以用来回答您的问题,具体取决于您需要做什么。我相信还有更多的方法可以做到。

例如,您可以通过简单地选择max(your_field)并按某些字段分组来提取组内的最大值,如果这是您所需要的。

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

如果您需要在查询中使用该最大值作为过滤条件,则可以通过在子查询中使用子查询和max执行伪分组来实现(注意我如何将BNAME检查移出子查询,这意味着我不必使用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 )

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

最后,如果您需要基于组合键进行检查,并将其与多个聚合函数结果进行比较,则实现将在很大程度上取决于您的需求的细节(由于您的问题没有,因此我将提供一个通用的)。最简单的选择是使用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个查询都可以使用连接来获得相同的结果。

请在下面找到我的答案。

  • 语法不支持子查询的连接: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比较。

左连接不支持小于比较,外连接只支持EQ比较:

SELECT * FROM X AS X LEFT JOIN X AS xmax ON X -key1 = xmax-key1 AND X -key2 <如果xmax-key是INITIAL>

这不是真的。这个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 <> ''.

并且至少从2008年7月7日起有效,所以在你问这个问题的时候它也是有效的。

相关内容

  • 没有找到相关文章

最新更新