在查询中有多个公共表达式(CTE)时,存在一个单一的递归CTE。

huangapple go评论67阅读模式
英文:

Having a single recursive CTE while there are multiple CTEs in a query

问题

我不确定以前是否已经提过这个问题,但我已经在不同的论坛上搜索过,没有找到确切的答案。我们是否应该总是将单词RECURSIVE初始化为第一个CTE(即使它不是递归CTE)以使整个查询运行?

示例查询:

-- 初始化一些数据
with temp_cte1 as (
  select
  100 as id,
  'test' as name,
  30000 as salary,
  date('2011-10-28') as start_date,
  date('2011-11-30') as end_date
),

-- 这个CTE用于获取开始和结束日期之间的所有日期
temp_cte2 as (
  select
    id,
    start_date as curr_day,
    end_date
  from temp_cte1
  union all
  select 
    id,
    DATE_ADD(curr_day, INTERVAL 1 DAY) as curr_day,
    end_date
  from temp_cte2
  where curr_day < end_date
),

-- 这个CTE用于从tempcte2中筛选出特定的日期
temp_cte3 as (
  select
    id,
    count(*) as pay_days
  from temp_cte2
  where DAY(curr_day) in (1, 15)
  group by id
)

select 
  d.id,
  d.name,
  d.salary,
  d.start_date,
  d.end_date,
  f.pay_days
from temp_cte1 d
left join temp_cte3 f
on d.id = f.id

上述查询会报错,表temp_cte2不存在:
错误响应:错误代码:1146. 表'final.temp_cte2'不存在

-- 初始化一些数据
with recursive temp_cte1 as (
  select
  100 as id,
  'test' as name,
  30000 as salary,
  date('2011-10-28') as start_date,
  date('2011-11-30') as end_date
),

-- 这个CTE用于获取开始和结束日期之间的所有日期
temp_cte2 as (
  select
    id,
    start_date as curr_day,
    end_date
  from temp_cte1
  union all
  select 
    id,
    DATE_ADD(curr_day, INTERVAL 1 DAY) as curr_day,
    end_date
  from temp_cte2
  where curr_day < end_date
),

-- 这个CTE用于从tempcte2中筛选出特定的日期
temp_cte3 as (
  select
    id,
    count(*) as pay_days
  from temp_cte2
  where DAY(curr_day) in (1, 15)
  group by id
)

select 
  d.id,
  d.name,
  d.salary,
  d.start_date,
  d.end_date,
  f.pay_days
from temp_cte1 d
left join temp_cte3 f
on d.id = f.id

但是,如果我在起始的CTE中使用关键词RECURSIVE初始化(即使该CTE不是递归的),查询就可以正常运行。有人能解释为什么我应该在顶部使用关键词RECURSIVE初始化递归CTE吗?

我想知道为什么我们必须在第一个CTE中使用关键词RECURSIVE。

英文:

I am not sure if this has been asked before but I have searched across different forums and haven't found the exact answer. Should we always initialize the word RECURSIVE to the first CTE (even though it's not the recursive CTE) for the entire query to run?

Example Query:

-- initalising some data
with temp_cte1 as (
  select
  100 as id,
  &#39;test&#39; as name,
  30000 as salary,
  date(&#39;2011-10-28&#39;) as start_date,
  date(&#39;2011-11-30&#39;) as end_date
),

-- this cte is to get all the dates between the start and end dates
temp_cte2 as (
  select
    id,
    start_date as curr_day,
    end_date
  from temp_cte1
  union all
  select 
    id,
    DATE_ADD(curr_day, INTERVAL 1 DAY) as curr_day,
    end_date
  from temp_cte2
  where curr_day &lt; end_date
),

-- this cte is filter out specific dates from tempcte2
temp_cte3 as (
  select
    id,
    count(*) as pay_days
  from temp_cte2
  where DAY(curr_day) in (1, 15)
  group by id
)

select 
  d.id,
  d.name,
  d.salary,
  d.start_date,
  d.end_date,
  f.pay_days
from temp_cte1 d
left join temp_cte3 f
on d.id = f.id

The above query throws the error that table temp_cte2 doesn't exist:
Error Response: Error Code: 1146. Table 'final.temp_cte2' doesn't exist

-- initalising some data
with recursive temp_cte1 as (
  select
  100 as id,
  &#39;test&#39; as name,
  30000 as salary,
  date(&#39;2011-10-28&#39;) as start_date,
  date(&#39;2011-11-30&#39;) as end_date
),

-- this cte is to get all the dates between the start and end dates
temp_cte2 as (
  select
    id,
    start_date as curr_day,
    end_date
  from temp_cte1
  union all
  select 
    id,
    DATE_ADD(curr_day, INTERVAL 1 DAY) as curr_day,
    end_date
  from temp_cte2
  where curr_day &lt; end_date
),

-- this cte is filter out specific dates from tempcte2
temp_cte3 as (
  select
    id,
    count(*) as pay_days
  from temp_cte2
  where DAY(curr_day) in (1, 15)
  group by id
)

select 
  d.id,
  d.name,
  d.salary,
  d.start_date,
  d.end_date,
  f.pay_days
from temp_cte1 d
left join temp_cte3 f
on d.id = f.id

But if I initialize with the keyword RECURSIVE in the starting CTE (even though that CTE isn't recursive), the query runs fine. Could someone explain why I should initialize a recursive CTE with the keyword RECURSIVE at the top?

I want to know why we have to use the keyword RECURSIVE at the first cte.

答案1

得分: 1

以下是翻译好的部分:

关键字WITH和RECURSIVE与所有的CTE相关,不仅仅是列表中的第一个。RECURSIVE仅表示在您的CTE中可能存在递归逻辑,而不是任何特定的CTE(或所有CTE)都是递归的。

英文:

The keywords WITH and RECURSIVE are associated to all your CTEs, not just the first one in the list. RECURSIVE just means that there may be recursive logic within your CTEs, not that any one specific CTE (or all of them) are recursive

huangapple
  • 本文由 发表于 2023年6月9日 07:08:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/76436234.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定