1

对于 JEST 表中的每个对象编号,我想获得一个我认为是主要状态的状态。

主要问题是,在我的情况下,我认为像 I0076 (删除标志)这样的独特状态可以与创建的其他状态(I0001)同时处于活动状态。在这种情况下,我想使用 GROUP BY objnr,然后在 I0076 始终覆盖任何其他状态的状态下使用 CASE。

ABAP CDS 或 SQL 有可能吗?还是我必须编写 ABAP 代码(AMDP 或后处理)来解决这个问题?

输入:

+-------+-------+
| OBJNR | STAT  |
+-------+-------+
| OBJ1  | I0001 |
| OBJ1  | I0076 |
| OBJ2  | I0001 |
+-------+-------+

输出:

+-------+-------+
| OBJ1  | I0076 |
| OBJ2  | I0001 |
+-------+-------+
4

2 回答 2

2

您可以在 CDS 视图定义中构建您的状态优先级,并在CASE条件和COALESCE. 如果您的状态被分成两组相互排斥的状态(比如“覆盖”和“非覆盖”),那么只有一个COALESCE和一个就足够了CASE

像这样:

define view z_demo_v as select from jest {
  OBJNR,
  coalesce(
// Overriding statuses
    max( case when STAT = 'I0076' /*and other overriding values go here*/ then STAT end ),
// Non-overriding statuses. All overriding are captured in previous CASE
//so no need to exclude them here, coalesce will return the first MAX
    max( STAT)
  ) as STAT
}

  where INACT = ''
  group by OBJNR

如果您可以在每个组中拥有多个状态,那么您可以根据coalesce需要嵌套尽可能多的优先级状态(因为在 CDScoalesce函数中只接受两个参数,但在 SQL 中它可以有很多)。

define view z_demo_v as select from jest {
  OBJNR,
  coalesce(
    coalesce(
      // Status with highest priority
      max( case STAT when 'I0076' then 'I0076' end ),
      // Status with second-highest priority
      max( case STAT when 'I0070' then 'I0070' end )
    ),
    // Status with other priority (that should be mutually exclusive)
    max( STAT)
  ) as STAT
}

  where INACT = ''
  group by OBJNR

当然,它需要针对新状态进行更新,但由于 CDS 语法有限,我看不到轻量级选项。

对于更强大的解决方案,您可以创建另一个 CDS 视图,该视图将包含具有以下结构的状态优先级:

| STATUS   | PRIORITY |
| (CHAR 5) | (INT)    |
+----------+----------+
| I0001    | 1        |
| I0011    | 2        |
| I0076    | 100      |
| I0079    | 101      |

其中每个覆盖状态将被赋予更高的优先级,优先级应唯一标识状态。它可以取自您直接设置优先级的某个 Z 表,或者取自自定义设置(如果它们可用),或者取自您编码的 AMDP(例如,对最后 3 个字符进行子串化并通过row_number()函数对其进行排序)。

然后,您需要将两个视图与该视图连接:

  • 第一个视图会将状态代码转换为状态优先级并计算优先级最高的状态:MAX( PRIORITY ) as FINAL_STATUS
  • 第二个视图会将其翻译回来:FINAL_STATUS -> PRIORITY -> STATUS。
define view z_stat_prio_v as select from z_statprio_t {
  STATUS,
  PRIORITY
}

define view z_demo_stat_last_v as select
  from jest as j
  join z_stat_prio_v as p
  on j.stat = p.status
 {
  j.OBJNR,
  max( p.PRIORITY ) as FINAL_STATUS
}

  where j.INACT = ''
  group by j.OBJNR


define view z_demo_stat_v as select
  from z_demo_stat_last_v as s
  join z_stat_prio_v as p
  on s.final_status = p.priority
 {
  s.OBJNR,
  p.STATUS as STAT
}

UPD:如果您I0076在任何一般状态 ( I0001) 之后始终具有压倒一切的状态 ( 在您的情况下),那么您可以使用LEFT OUTER JOIN同一个JEST表就地过滤。在 SAP_ABA 750 SP 08 中成功激活了以下 DDL 源。

define view Z_TEST_V as select from JEST as j1
  left outer join JEST as j2
    on j1.OBJNR = j2.OBJNR
     and j2.STAT = 'I0076'
     and j2.INACT = ''
  {
  j1.OBJNR,
  coalesce (
    j2.STAT,
    j1.STAT
  ) as STAT

}
  where j1.INACT = ''
    and j1.STAT <> 'I0076'
于 2020-12-01T15:31:05.877 回答
2

您可以通过使用三个 CDS 视图来实现此目的。

  • 在第一个 CDS 视图中,您使用 where 语句仅选择已删除状态(其中 stat = 'I0076')
  • 在第二个 CDS 视图中,您使用 where 语句仅选择未删除状态(其中 stat <> 'I0076')
  • 在第三个 CDS 视图中,您在第一个和第二个视图上使用左外连接,并添加一个 case 语句以仅包含一个结果(当 First.stat 为 null 然后 Second.stat 否则 First.stat 以状态结束时的情况)
于 2020-12-01T09:24:33.360 回答