Postgre эквивалент MS SQL внешнее применение - PullRequest
0 голосов
/ 31 марта 2020

Приведенный ниже код отлично работает с MS SQL. Любое предложение о том, как перевести это на Postgre?

;with mySource  as (
  SELECT 1050
LineID, 1 SeqNo, NULL Val
UNION SELECT 1050 LineID, 2
SeqNo, NULL Val
UNION SELECT 1050 LineID, 3
SeqNo, 'ABC' Val
UNION SELECT 1050 LineID, 4
SeqNo, NULL Val
UNION SELECT 1050 LineID, 5
SeqNo, NULL Val
UNION SELECT 1050 LineID, 6
SeqNo, 'CDE' Val
UNION SELECT 1050 LineID, 7
SeqNo, NULL Val
UNION SELECT 1050 LineID, 8
SeqNo, NULL Val
UNION SELECT 1050 LineID, 9
SeqNo, 'EFG' Val
UNION SELECT 1050 LineID, 10
SeqNo, NULL Val
UNION SELECT 2222 LineID, 1
SeqNo, NULL Val
UNION SELECT 2222 LineID, 2
SeqNo, 'ABC' Val
UNION SELECT 2222 LineID, 3
SeqNo, 'CDE' Val
UNION SELECT 2222 LineID, 4
SeqNo, NULL Val
UNION SELECT 2222 LineID, 5
SeqNo, NULL Val
UNION SELECT 2222 LineID, 6
SeqNo, 'EFG' Val
UNION SELECT 2222 LineID, 7
SeqNo, NULL Val
UNION SELECT 2222 LineID, 8
SeqNo, 'HIJ' Val
UNION SELECT 2222 LineID, 9
SeqNo, NULL Val
UNION SELECT 2222 LineID, 10
SeqNo, 'KLM' Val
) 
Select LineID,SeqNo, Coalesce(bu,ba) Val 
from mySource m
outer apply (select top 1 Val 
from mySource m1 
WHERE m1.LineID=m.LineID and m1.SeqNo<=m.SeqNo and Val is not null 
Order by SeqNo DESC) d1(bu) 
outer APPLY (SELECT TOP 1 Val 
FROM mySource m3 
WHERE  m3.LineID=m.LineID and m3.SeqNo>= m.SeqNo AND Val IS NOT NULL 
ORDER  BY SeqNo) d3(ba)
ORDER BY m.LineID, m.SeqNo

1 Ответ

1 голос
/ 31 марта 2020

Эквивалент outer apply в Посгресе будет left join lateral. Вам также необходимо заменить TOP 1, то есть T- SQL speci c, на LIMIT.

Также возможно сократить общее табличное выражение, чтобы использовать синтаксис values().

with mySource(LineID, SeqNo, Val)  as (values
    (1050, 1, null),
    (1050, 2, null),
    (1050, 3, null),
    ...
    (2222, 10, 'KLM')
)
select LineID, SeqNo, Coalesce(bu,ba) Val 
from mySource m
left join lateral (
    select Val bu 
    from mySource m1 
    where m1.LineID = m.LineID and m1.SeqNo <= m.SeqNo and Val is not null 
    order by SeqNo desc
    limit 1
) d1 on true 
left join lateral (
    select Val ba
    from mySource m3 
    where m3.LineID = m.LineID and m3.SeqNo >= m.SeqNo AND Val is not null 
    order  by SeqNo
    limit 1
) d3 on true
order by m.LineID, m.SeqNo

Глядя на запрос, я склонен подозревать, что его логика c может быть значительно упрощена с помощью оконных функций (на ум приходят lag() и lead()). Возможно, вы захотите задать еще один вопрос с более подробной информацией о том, что вы пытаетесь выполнить sh, а также с примерами данных и ожидаемыми результатами.

...