Замените коррелированный подзапрос соединением

Я хотел бы заменить следующий фрагмент 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 с несколько сниженной выразительностью). Увы, коррелированные подзапросы и операторы EXISTS не поддерживаются.

Я немного погуглил и нашел возможное решение (последнее сообщение) здесь https://archive.sap.com/discussions/thread/3824523

Тем не менее, предложение

  1. Выбор MAX(значение)
  2. Ваш сценарий с использованием внутреннего соединения с первым представлением CDS

не работает в моем случае.

  1. tf.bis (и tf.ab) должны быть в списке выбора нового представления, чтобы ограничить rhs объединения (нового представления) правильными временными рамками.
  2. Увы, может быть несколько (не перекрывающихся) подкадров (содержащихся в [tf.ab, tf.bis]) с одним и тем же tf.tarifart. Так как они не могут быть сгруппированы вместе, это приводит к нескольким строкам в правой части.

Исходный запрос не имеет проблемы с этим (нет объединения -> нет декартово произведение).

Я надеюсь, что следующая скрипка (рабочий пример) немного прояснит ситуацию: http://sqlfiddle.com/

Учитывая эти ограничения, мне кажется, что эквивалентное соединение действительно невозможно. Предложения или даже подтверждения?

1 ответ

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, чтобы уменьшить набор результатов до одного на документ.

Другие вопросы по тегам