При переходе с SQLite на SAP ASE/SQL Server требуется помощь при перезаписи запроса.

Я написал следующий запрос в SQLite, который работает нормально, но обнаружил, что в офисе используется SAP ASE (Sybase SQL Server), и он не отображает там тот же результат.

select
dm04_maf.mcn,
dm04_maf.wc_cd,
dm04_maf.buno_serno,
max(dm12_maf_note.maf_note) as Last_Note,
dm12_maf_note.note_dttm as Time_of_Note,
dm12_maf_note.orignr
from
dm04_maf
left join
dm12_maf_note on dm04_maf.mcn = dm12_maf_note.mcn
where dm04_maf.ty_maf_cd = 'TD'
group by dm04_maf.mcn

Я считаю, что он неправильно выполняет group by, поскольку он не дает мне последней заметки для каждого mcn (первичного ключа), он дает мне каждую заметку для каждого mcn.

Любые указания по этому поводу будут оценены.

2 ответа

Решение

Соответствует ANSI group by запрос будет иметь все неагрегированные столбцы (из select/projection list) также в group byпункт. Хотя многие СУБД допускают несовместимость с ANSI group by запросы (как в этом вопросе), как каждая СУБД решает обрабатывать указанные несовместимые с ANSI group by запрос открыт (т. е. нет гарантии получения одного и того же результата в разных СУБД).

Некоторые предположения:

  • OP упоминает о желании отображать только 'last note'; пока мы предполагаем, что max(maf_note) достаточно для определения 'last note' для данного mcn значение
  • другие неагрегированные столбцы (например, wc_cd, buno_serno, note_dttm и orignr) должен происходить из той же строки, которая производит last note = макс (maf_note)`

Поскольку SAP (Sybase) ASE не поддерживает функции Windows и ROW_NUMBER(), одна из идей - использовать подзапрос для поиска 'last note' а затем присоедините это к основному запросу, чтобы получить остальные желаемые значения, например:

select  dm1.mcn,
        dm1.wc_cd,
        dm1.buno_serno,
        dt.Last_Note,
        dmn1.note_dttm as Time_of_Note,
        dmn1.orignr

from    dm04_maf      dm1
left
join    dm12_maf_note dmn1
on      dm1.mcn = dmn1.mcn

join   (select dm2.mcn,
               max(dmn2.maf_note) as Last_Note

        from   dm04_maf      dm2
        join   dm12_maf_note dmn2
        on     dm2.mcn = dmn2.mcn

        where  dm2.ty_maf_cd = 'TD'
        group by dm2.mcn
       ) dt

on      dm1.mcn       = dt.mcn
and     dmn1.maf_note = dt.Last_Note
where  dm1.ty_maf_cd = 'TD'

ПРИМЕЧАНИЯ:

  • дополнительный dm1.ty_maf_cd = 'TD'вероятно, избыточный; оставит это на усмотрение OP, чтобы решить, сохранить или удалить
  • (очевидно) может потребоваться вернуться и настроить в зависимости от обоснованности предположений и / или обновлений вопроса

С участием ROW_NUMBER() оконная функция:

select t.mcn, t.wc_cd, t.buno_serno,
       t.maf_note as Last_Note,
       t.note_dttm as Time_of_Note,
       t.orignr 
from (
  select d04.mcn, d04.wc_cd, d04.buno_serno,
         d12.maf_note, d12.note_dttm, d12.orignr,
         row_number() over (partition by d04.mcn order by d12.maf_note desc) rn
  from dm04_maf d04 left join dm12_maf_note d12 
  on d04.mcn = d12.mcn
  where d04.ty_maf_cd = 'TD'
) t
where t.rn = 1
Другие вопросы по тегам