带有数组取消嵌套的 Redshift 递归 CTE 给出错误“set_cte_path 找不到 CTE”

问题描述 投票:0回答:1

这是我尝试为其构建查询的更复杂数据的简化版本,但说明了问题。

递归 CTE

dates
无需数组取消嵌套即可正常工作 - 取自此答案https://stackoverflow.com/a/70014766/2506034

取消嵌套查询记录在此处:https://docs.aws.amazon.com/redshift/latest/dg/query-super.html#unnest

这按预期运行

with recursive
    start_dt as (select '2024-12-01'::date s_dt),
    end_dt as (select dateadd(day, 1, '2025-01-01'::date)::date e_dt),
    -- the recursive cte, note declaration of the column `dt`
    dates (dt) as (
        -- start at the start date
        select s_dt dt from start_dt
        union all
        -- recursive lines
        select dateadd(day, 1, dt)::date dt  -- converted to date to avoid type mismatch
        from dates
        where dt <= (select e_dt from end_dt)  -- stop at the end date
),
all_dates as (
    select dt as range_date
    from dates
),
test_data as (
    select 'test1' as account_id, '2025-01-01' as date, array('123', '456') as ids_array
    union
    select 'test2' as account_id, '2025-01-01' as date, array('789', '101') as ids_array
),
test_data_with_dates as (
    select td.*
    from test_data td
    join all_dates d on d.range_date = td.date
)
select tdd.* from test_data_with_dates as tdd

结果:

account_id,date,ids_array
test2,2025-01-01,["789","101"]
test1,2025-01-01,["123","456"]

整个查询中无需任何递归 CTE 即可取消嵌套:

with test_data as (
    select 'test1' as account_id, '2025-01-01' as date, array('123', '456') as ids_array
    union
    select 'test2' as account_id, '2025-01-01' as date, array('789', '101') as ids_array
),
test_data_with_dates as (
    select td.*
    from test_data td
)
select tdd.account_id, id from test_data_with_dates as tdd, tdd.ids_array as id

结果:

account_id,id
test1,"123"
test1,"456"
test2,"789"
test2,"101"

但是递归+取消嵌套给出了

with recursive
    start_dt as (select '2024-12-01'::date s_dt),
    end_dt as (select dateadd(day, 1, '2025-01-01'::date)::date e_dt),
    -- the recursive cte, note declaration of the column `dt`
    dates (dt) as (
        -- start at the start date
        select s_dt dt from start_dt
        union all
        -- recursive lines
        select dateadd(day, 1, dt)::date dt  -- converted to date to avoid type mismatch
        from dates
        where dt <= (select e_dt from end_dt)  -- stop at the end date
),
all_dates as (
    select dt as range_date
    from dates
),
test_data as (
    select 'test1' as account_id, '2025-01-01' as date, array('123', '456') as ids_array
    union
    select 'test2' as account_id, '2025-01-01' as date, array('789', '101') as ids_array
),
test_data_with_dates as (
    select td.*
    from test_data td
    join all_dates d on d.range_date = td.date
)
select tdd.account_id, id from test_data_with_dates as tdd, tdd.ids_array as id

ERROR: set_cte_path cannot find CTE dates

sql amazon-web-services amazon-redshift
1个回答
0
投票

只有第一个 CTE 可以递归 - 您将其设置为第三个。 只需将 start_dt 和 end_dt 作为子查询带入日期 CTE 中,事情应该会更好。

[您缩进前 3 个 CTE 的格式可能会导致混乱]

© www.soinside.com 2019 - 2024. All rights reserved.