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

MySQL递归CTE查询:基于GetTicketNumbers表生成序列行

问题描述

现有GetTicketNumbers表数据如下:

i    UID                                 TicketNumber
   2    09901a22c7c3acc6786847c775f1d113    10
   6    00dad28bef21f916240d6e8c1c1bd67d    5
  12    00dad28bef21f916240d6e8c1c1bd67d    20

需要生成总计35行结果(必须保留UID用于上层关联):对应原表i=2的行生成10条序列行,i=6的行生成5条,i=12的行生成20条。现有不完整的递归CTE查询,请求补全:

With RECURSIVE cte (i, UID, TicketNumbers) as
 (
     Select i, UID, TicketNumbers from GetTicketNumbers 
     union all
     Select i + 1, UID, TicketNumbers from cte where ?????
 ) select * from cte order by i;

环境为MySQL。


解决方案

首先要明确递归终止逻辑:对每一行初始数据,需生成从原i开始的连续TicketNumber行数据。原CTE缺少对起始i的记录,无法正确判断递归终止时机,以下是两种可行的补全方案:

方案一:新增起始值字段(推荐,效率更高)

通过新增start_i字段存储初始行的i值,避免递归时重复查询原表,逻辑更清晰:

WITH RECURSIVE cte (i, UID, TicketNumber, start_i) AS (
    -- 初始查询:保留原始行的i作为起始值start_i
    SELECT i, UID, TicketNumber, i FROM GetTicketNumbers
    UNION ALL
    -- 递归生成下一行,直到当前i达到起始i + TicketNumber - 1
    SELECT i + 1, UID, TicketNumber, start_i FROM cte
    WHERE i < start_i + TicketNumber - 1
)
-- 输出所需列,去掉临时的start_i字段
SELECT i, UID, TicketNumber FROM cte ORDER BY i;

方案二:使用子查询获取起始值(不修改原CTE结构)

如果要保留原CTE的字段结构,可通过子查询获取当前行的起始i值,补全WHERE条件:

WITH RECURSIVE cte (i, UID, TicketNumber) AS (
    SELECT i, UID, TicketNumber FROM GetTicketNumbers
    UNION ALL
    SELECT i + 1, UID, TicketNumber FROM cte
    WHERE i < (SELECT g.i FROM GetTicketNumbers g WHERE g.UID = cte.UID AND g.TicketNumber = cte.TicketNumber) + cte.TicketNumber - 1
)
SELECT * FROM cte ORDER BY i;

效果说明

两种方案都能生成符合要求的35行数据:

  • i=2生成10行(范围2~11)
  • i=6生成5行(范围6~10)
  • i=12生成20行(范围12~31)
    且全程保留UID字段,满足上层关联需求。

内容的提问来源于stack exchange,提问作者Alex-1999

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 12:22:08