将SQL Server/C#编写的时段生成CTE查询转换为PostgreSQL版本
问题排查
你报错的核心原因有3点:
- 递归CTE的递归部分没有引用上级CTE(
TIMESLOTS),数据库无法定位start、end列的来源 - PostgreSQL 递归 CTE 必须显式添加
RECURSIVE关键字,否则不会识别为递归逻辑 - 缺少递归终止条件,会触发无限循环报错
正确转换代码
完全对齐原SQL Server参数化逻辑版本
WITH RECURSIVE TIMESLOTS AS ( -- 基础分支:生成当日第一个预约时段 SELECT @StartTime::time AS "start", (@StartTime + (@DesiredLength || ' minutes')::interval)::time AS "end" UNION ALL -- 递归分支:生成后续时段,超过闭店时间自动终止 SELECT "start" + (@Interval || ' minutes')::interval AS "start", "end" + (@Interval || ' minutes')::interval AS "end" FROM TIMESLOTS WHERE ("end" + (@Interval || ' minutes')::interval)::time <= @EndTime::time ) SELECT * FROM TIMESLOTS;
硬编码参数示例版本(对应你自行改写的逻辑)
WITH RECURSIVE TIMESLOTS AS ( SELECT '09:00'::time AS "start", '09:30'::time AS "end" UNION ALL SELECT "start" + interval '30 minutes', "end" + interval '30 minutes' FROM TIMESLOTS -- 可自行调整终止时间 WHERE "end" + interval '30 minutes' <= '18:00'::time ) SELECT * FROM TIMESLOTS;
语法差异说明
- PostgreSQL 时间运算直接使用
interval类型加减即可,不需要调用dateadd函数 - 双引号用于包裹区分大小写的标识符,
start、end属于SQL关键字,作为列名使用时必须加双引号 - 单引号用于包裹字符串、时间类文本值
内容的提问来源于stack exchange,提问作者Teamouts 002
相关产品推荐
相关产品推荐

