Postgre 等效于 MSSQL 外部应用

Postgre equivalent of MSSQL outer apply

以下代码适用于 MSSQL。关于如何将其翻译成 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

Posgres 中 outer apply 的等价物是 left join lateral。您还需要将特定于 T-SQL 的 TOP 1 替换为 LIMIT.

也可以缩短常见的 table 表达式以使用 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

查看查询,我倾向于怀疑它的逻辑可以用 window 函数大大简化(想到 lag()lead())。您可能想问另一个问题,详细了解您要完成的工作,以及示例数据和预期结果。