The below code works fine with MSSQL. Any suggestion on how to translate this to 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
The equivalent for outer apply
in Posgres would be left join lateral
. You also need to replace TOP 1
, which is T-SQL specific, with LIMIT
.
It is also possible to shorten the common table expression to use the values()
syntax.
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
Looking at the query, I tend to suspect that its logic could be largely simplified with window functions (lag()
and lead()
come to mind). You might want to ask another question with more details on what you are trying to accomplish, along with sample data and expected results.