Вложенная группировка во внутренней таблице

Я хотел бы получить все строки, которые имеют разные записи в полях anln1 и ​​anln2. Для этого мне нужен подходящий оператор OpenSQL.

Например. есть следующая таблица:

anln1 | anln2 | datum    | psp      | przt
------------------------------------------
10007 | 0     | 20140101 | 12345678 | 1
10007 | 0     | 20140101 | 11111111 | 99
10007 | 1     | 20140101 | 12345678 | 1
10007 | 1     | 20140101 | 11111111 | 99

Все записи для anln1 + anln2 должны повторять комбинацию данных, psp и przt если есть другой подномер, например anln2 = 1.

К сожалению, в моей таблице есть нарушения этой спецификации (SQLFiddle: http://sqlfiddle.com/#!2/f5d1f):

anln1 | anln2 | datum    | psp      | przt
------------------------------------------
10000 | 0     | 20140101 | 12345678 | 60
10000 | 0     | 20140101 | 11111111 | 40
10000 | 1     | 20140101 | 11111111 | 100
10000 | 2     | 20140101 | 11111111 | 100
10000 | 3     | 20140101 | 22222222 | 100
10001 | 0     | 20140101 | 12312312 | 100
10001 | 1     | 20140101 | 12312312 | 100
10001 | 2     | 20140101 | 12312312 | 100
10002 | 0     | 20140101 | 11111111 | 100
10003 | 0     | 20140101 | 11111111 | 100
10004 | 0     | 20140101 | 11111111 | 100
10005 | 0     | 20140101 | 22222222 | 100
10005 | 1     | 20140101 | 33333333 | 100
10006 | 0     | 20140101 | 11111111 | 20
10006 | 0     | 20140101 | 22222222 | 80
10006 | 1     | 20140101 | 11111111 | 30
10006 | 1     | 20140101 | 11111111 | 70
10007 | 0     | 20140101 | 12345678 | 1
10007 | 0     | 20140101 | 11111111 | 99
10007 | 1     | 20140101 | 12345678 | 1
10007 | 1     | 20140101 | 11111111 | 99

В результате для моего запроса мне нужно идентифицировать все строки, в которых нарушена моя спецификация. Правильные строки следует просто опустить. Правильные строки - это те, где anln1 равно 10001, 10002, 10003, 10004, 10007.

Итак, результат должен выглядеть так:

anln1 | anln2 | datum    | psp      | przt
------------------------------------------
10000 | 0     | 20140101 | 12345678 | 60
10000 | 0     | 20140101 | 11111111 | 40
10000 | 1     | 20140101 | 11111111 | 100
10000 | 2     | 20140101 | 11111111 | 100
10000 | 3     | 20140101 | 22222222 | 100
10005 | 0     | 20140101 | 22222222 | 100
10005 | 1     | 20140101 | 33333333 | 100
10006 | 0     | 20140101 | 11111111 | 20
10006 | 0     | 20140101 | 22222222 | 80
10006 | 1     | 20140101 | 11111111 | 30
10006 | 1     | 20140101 | 11111111 | 70

Я пробовал что-то с GROUP BY, HAVING и COUNT (...)> 1, но не получил полезного результата. Можно ли это решить с помощью (Open) SQL?

Очень жду вашей помощи! Пожалуйста, используйте мой SQLFiddle (http://sqlfiddle.com/#!2/f5d1f), чтобы попробовать около.


person K B    schedule 12.01.2015    source источник
comment
Не уверен, что не так, но ... на первый взгляд, все записи уникальны, поэтому HAVING COUNT (*) не помогает. Попробуйте удалить anln2 из оператора select и проверьте его снова.   -  person Maciej Los    schedule 12.01.2015


Ответы (2)


После выбора записей с anln2 ‹> 0 я работал с внутренней таблицей.

Сначала я отсортировал выбранный результат следующим образом:

 SORT gt_internaltable BY anln1 anln2 datum psp przt. 

Затем я перебрал внутреннюю таблицу и удалил все двойные записи ...

 LOOP AT gt_internaltable INTO gs_tablerow.
    AT NEW anln1.
      CLEAR g_count.
    ENDAT.

    g_count = g_count + 1.

    AT END OF anln1.
      IF g_count > 1. " delete double entries
        DELETE gt_internaltable WHERE anln1 = gs_tablerow-anln1
                         AND   anln2 = gs_tablerow-anln2
                         AND   datum = gs_tablerow-datum
                         AND   psp = gs_tablerow-psp
                         AND   przt = gs_tablerow-przt.
      ENDIF.
    ENDAT.
  ENDLOOP.

В конце концов, список записей, нарушающих мою спецификацию, остается в gt_internaltable.

person K B    schedule 30.06.2015

Я не думаю, что это достижимо через OpenSQL.

Вот как добиться этого, используя современный синтаксис ABAP с использованием группировки:

TYPES: BEGIN OF ty_anla,
        anln1 TYPE anln1,
        anln2 TYPE anln2,
        datum TYPE erdat,
        psp   TYPE c LENGTH 8,
        przt  TYPE i,
       END OF ty_anla,
       tty_anla TYPE STANDARD TABLE OF ty_anla WITH NON-UNIQUE KEY primary_key COMPONENTS anln1.

DATA: lt_input TYPE tty_anla,
      lt_output TYPE tty_anla.

lt_output = lt_input = 
VALUE #( ( anln1 = 10000 anln2 = 0 datum = '20140101' psp = 12345678 przt = 60 )
         ( anln1 = 10000 anln2 = 0 datum = '20140101' psp = 11111111 przt = 40 )
         ( anln1 = 10000 anln2 = 1 datum = '20140101' psp = 11111111 przt = 100 )
         ( anln1 = 10000 anln2 = 2 datum = '20140101' psp = 11111111 przt = 100 )
         ( anln1 = 10000 anln2 = 3 datum = '20140101' psp = 22222222 przt = 100 )
         ( anln1 = 10001 anln2 = 0 datum = '20140101' psp = 12312312 przt = 100 )
         ( anln1 = 10001 anln2 = 1 datum = '20140101' psp = 12312312 przt = 100 )
         ( anln1 = 10001 anln2 = 2 datum = '20140101' psp = 12312312 przt = 100 )
         ( anln1 = 10002 anln2 = 0 datum = '20140101' psp = 11111111 przt = 100 )
         ( anln1 = 10003 anln2 = 0 datum = '20140101' psp = 11111111 przt = 100 )
         ( anln1 = 10004 anln2 = 0 datum = '20140101' psp = 11111111 przt = 100 )
         ( anln1 = 10005 anln2 = 0 datum = '20140101' psp = 22222222 przt = 100 )
         ( anln1 = 10005 anln2 = 1 datum = '20140101' psp = 33333333 przt = 100 )
         ( anln1 = 10006 anln2 = 0 datum = '20140101' psp = 11111111 przt = 20 )
         ( anln1 = 10006 anln2 = 0 datum = '20140101' psp = 22222222 przt = 80 )
         ( anln1 = 10006 anln2 = 1 datum = '20140101' psp = 11111111 przt = 30 )
         ( anln1 = 10006 anln2 = 1 datum = '20140101' psp = 11111111 przt = 70 )
         ( anln1 = 10007 anln2 = 0 datum = '20140101' psp = 12345678 przt = 1 )
         ( anln1 = 10007 anln2 = 0 datum = '20140101' psp = 11111111 przt = 99 )
         ( anln1 = 10007 anln2 = 1 datum = '20140101' psp = 12345678 przt = 1 )
         ( anln1 = 10007 anln2 = 1 datum = '20140101' psp = 11111111 przt = 99 )
                                                                  ).

LOOP AT lt_input ASSIGNING FIELD-SYMBOL(<fs_inp>) USING KEY primary_key GROUP BY ( anln1 = <fs_inp>-anln1 index = GROUP INDEX size = GROUP SIZE ) REFERENCE INTO DATA(common_anln1).
LOOP AT GROUP common_anln1 ASSIGNING FIELD-SYMBOL(<fs_member>) GROUP BY ( datum = <fs_member>-datum psp = <fs_member>-psp przt = <fs_member>-przt index = GROUP INDEX size = GROUP SIZE ) REFERENCE INTO DATA(common_key).
 DATA(common_key_size) = common_key->*-size.
 EXIT.
ENDLOOP.
 CHECK common_anln1->*-size = common_key_size.
 DELETE lt_output WHERE anln1 = common_anln1->*-anln1.
ENDLOOP.

Здесь мы группируем сначала по ANLN1 ключу, а затем в этих группах мы проверяем datum+psr+psp ключ , чтобы размеры групп были равны. Это означает, что все ANLN1 имеют один и тот же ключ.

В результате в lt_output вы увидите желаемый результат:

  10000   0 2014-01-01 12345678 60 
  10000   0 2014-01-01 11111111 40 
  10000   1 2014-01-01 11111111 100 
  10000   2 2014-01-01 11111111 100 
  10000   3 2014-01-01 22222222 100 
  10005   0 2014-01-01 22222222 100 
  10005   1 2014-01-01 33333333 100 
  10006   0 2014-01-01 11111111 20 
  10006   0 2014-01-01 22222222 80 
  10006   1 2014-01-01 11111111 30 
  10006   1 2014-01-01 11111111 70 
  10007   0 2014-01-01 12345678 1 
  10007   0 2014-01-01 11111111 99 
  10007   1 2014-01-01 12345678 1 
  10007   1 2014-01-01 11111111 99 

10007 здесь, потому что это неправильная строка согласно вашему определению Все записи для anln1 + anln2 должны повторять свою комбинацию данных, psp и przt. Разные значения 10007 anln2 имеют разные значения psp.

person Suncatcher    schedule 07.10.2020