繁体   English   中英

带有 Oracle SQL (PL/SQL) 集合的窗口函数(前导/滞后)

[英]Window functions (lead/lag) with collections in Oracle SQL (PL/SQL)

我想将 PostgreSQL 中存在的 SQL 脚本移植到 Oracle SQL。 这是示例数据:

NR                      GRD DT
00000000000000000001    06  01.01.13
00000000000000000001    06  01.01.13
00000000000000000001    21  01.01.13
00000000000000000002    06  01.01.13
00000000000000000002    21  01.01.13
00000000000000000004    01  31.03.13

这是我的简化代码:

CREATE TYPE tbl_array AS TABLE OF NVARCHAR2(4000);

with prep as (
Select
    nr
    , cast(collect(grd) as tbl_array) grds
from
    test_table
group by
    nr                    
)
select 
    prep.*
    , lead(grds) over (order by nr) as lead_grds
from 
    prep

但是窗口函数不起作用。 我收到以下错误消息:

ORA-00932: 不一致的数据类型:预期 - 得到 ORACLEANALYTICS.TBL_ARRAY

是因为创建的类型吗? 我该如何解决这个问题? 在第二步中,我想检查集合与其他集合的交集(已经在工作),所以我需要它们。 这有可能吗?

干杯克里斯

您可以使用ROW_NUMBER()来模拟LAG/LEAD

with prep as (
  select
    nr, CAST(collect(grd) AS tbl_array) grds,ROW_NUMBER() OVER(ORDER BY nr) AS rn
  from tab
  group by nr                    
)
select p.nr, p.grds, p2.grds AS lead_grds
    --, lead(grds) over (order by nr) as lead_grds
from prep p
LEFT JOIN prep p2
  ON p2.rn = p.rn +1;

准备输出:

┌──────────────────────┬────────────────────────────────┬────┐
│          NR          │              GRDS              │ RN │
├──────────────────────┼────────────────────────────────┼────┤
│ 00000000000000000001 │ HR.TBL_ARRAY('06', '21', '06') │  1 │
│ 00000000000000000002 │ HR.TBL_ARRAY('06', '21')       │  2 │
│ 00000000000000000004 │ HR.TBL_ARRAY('01')             │  3 │
└──────────────────────┴────────────────────────────────┴────┘

整个查询的输出:

┌──────────────────────┬──────────────────────────────┬──────────────────────────┐
│          NR          │             GRDS             │        LEAD_GRDS         │
├──────────────────────┼──────────────────────────────┼──────────────────────────┤
│ 00000000000000000001 │HR.TBL_ARRAY('06', '21', '06')│ HR.TBL_ARRAY('06', '21') │
│ 00000000000000000002 │HR.TBL_ARRAY('06', '21')      │ HR.TBL_ARRAY('01')       │
│ 00000000000000000004 │HR.TBL_ARRAY('01')            │                          │
└──────────────────────┴──────────────────────────────┴──────────────────────────┘

在 PostgreSQL 中等效:

WITH prep AS (
  SELECT NR, ARRAY_AGG(GRD) AS grds
  FROM tab
  GROUP BY NR
)
SELECT prep.*, LEAD(grds) OVER(ORDER BY nr) AS lead_grds
FROM prep;

DBFiddle 演示

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM