You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将含KEEP子句的Oracle SQL转换为PostgreSQL等效语句

Oracle 特殊窗口语法转 PostgreSQL 等效实现

原语句逻辑说明

待转换的Oracle SQL使用了KEEP(DENSE_RANK LAST)专属语法,核心逻辑为:按NUMBER字段分区,每个分区内以UPD_DATE升序排列(NULL值排在最前),取排序后排名最末位的分组中最大的USER_ID值,作为同分区所有行的返回结果。
原SQL代码如下:

SELECT 
     MAX(TKI1.USER_ID)
     KEEP(DENSE_RANK LAST ORDER BY TKI1.UPD_DATE NULLS FIRST)
     OVER(PARTITION BY TKI1.NUMBER) AS  USER_ID         
 FROM
    USER_TABLE TKI1;

PostgreSQL 可直接执行的等效语句

PostgreSQL没有原生的KEEP子句支持,通过标准窗口函数+FILTER过滤即可实现完全一致的逻辑,写法如下:

SELECT
    MAX(TKI1.USER_ID) FILTER (WHERE rk = 1) OVER (PARTITION BY TKI1."NUMBER") AS USER_ID
FROM (
    SELECT
        *,
        DENSE_RANK() OVER (
            PARTITION BY "NUMBER" 
            ORDER BY UPD_DATE DESC NULLS LAST
        ) AS rk
    FROM USER_TABLE TKI1
) TKI1;

逻辑对应说明

  • 原语句DENSE_RANK LAST ORDER BY UPD_DATE NULLS FIRST的本质是取分区内UPD_DATE值最大的记录分组:升序排列时NULL排在最前,意味着NULL为最小的UPD_DATE值,排序最末尾的就是UPD_DATE最大的分组。PostgreSQL中通过ORDER BY UPD_DATE DESC NULLS LAST倒序排列,排名rk=1的记录刚好对应原逻辑中最末位的DENSE_RANK分组。
  • 外层MAX(USER_ID) FILTER (WHERE rk = 1)配合分区窗口,等效于原KEEP子句中取目标分组内最大USER_ID的逻辑。
  • 注意NUMBER是PostgreSQL保留关键字,如果字段名确实为NUMBER,必须用双引号包裹,否则会触发语法错误。

内容的提问来源于stack exchange,提问作者tantn10

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 23:30:51