【问题标题】:Recursive SELECT query to return rates of arbitrary depth?递归 SELECT 查询返回任意深度的速率?
【发布时间】:2013-12-15 10:07:09
【问题描述】:

这是我第一次尝试递归SQL查询向上遍历N个父子关系,不知道从哪里开始。任何帮助将不胜感激。

场景是我有两个表 - raterate_plan。费率属于适用于用户的费率计划。

CREATE TERM rate_plan (
   id                  integer PRIMARY KEY NOT NULL
                       DEFAULT nextval('rate_plan_id'),

   descr               varchar(64) NOT NULL,

   parent_rate_plan_id integer NOT NULL REFERENCES rate_plan(id)
);

CREATE TABLE rate (
   id                integer PRIMARY KEY NOT NULL
                     DEFAULT nextval('rate_id'),

   prefix            varchar(24) NOT NULL,

   rate_plan_id      integer NOT NULL 
                     REFERENCES rate_plan(id)
);

获取费率的典型查询:

SELECT * FROM rate  
   WHERE (
      rate_plan_id = ${user rate plan ID} 
      AND prefix = ${prefix}
   )
   ORDER BY LENGTH(prefix) ASC;

我想要返回最具体的(LENGTH()-iest 前缀)费率,但不限于${user rate plan ID},而是从@987654329 中与任意数量的费率计划相关联的费率中挑选@ 等级制度。当rate_plan.parent_rate_plan_id = NULL 时,递归应该触底。

我只想做一个JOIN,但我需要容纳 N 个父子关系,而不仅仅是两个。

这是在 PostgreSQL 9.x 上。我尝试了WITH RECURSIVEUNION ALL,在每个SELECT 上加入rate_planrate,并尝试按父级过滤,但由于对这些构造如何工作的理解不足,所以没有成功。

【问题讨论】:

  • 我不完全理解你想要做什么。但是在 CTE 的文档中,有一个图形查询示例,它使用数组构建父节点的路径。对你的树做同样的事情:你想要的查询应该(希望)是显而易见的,例如每个节点的父节点都包含带有您的前缀的节点,或者您正在寻找的任何内容。
  • 你能准备一些示例数据(一些插入)并将其输入到这个 sqlfiddle:sqlfiddle.com/#!15/89073/1 吗?然后附上 SQLFiddne 的链接,并在此数据的基础上说明您的要求并显示预期结果。
  • Postgres major versions 包括点后的第一个数字。当前版本是9.3

标签: sql postgresql common-table-expression recursive-query


【解决方案1】:

根据您的描述,这可能是您正在寻找的:

最具体的(LENGTH()-iest 前缀)率,但不受限制 到${user rate plan ID},而是从那些附属的人那里挑选费率

WITH RECURSIVE cte AS (
   SELECT id, parent_rate_plan_id
   FROM   rate_plan  
   WHERE  id = ${user rate plan ID} 

   UNION ALL
   SELECT rp.id, rp.parent_rate_plan_id
   FROM   cte
   JOIN   rate_plan rp ON rp.id = cte.parent_rate_plan_id
   )
SELECT *
FROM   cte
JOIN   rate r ON r.rate_plan_id = cte.id
ODER   BY length(prefix) DESC
LIMIT  1;

一旦到达顶部节点 (parent_rate_plan_id IS NULL),递归就会自动停止。

集齐所有计划后加入rate 一次更有效。

The manual on (recursive) CTEs.

【讨论】:

  • 这似乎是正确的想法;但是,Postgres 不允许我以“WITH cte”的形式运行它,抱怨它是自我引用的。但是当我将它作为 WITH RECURSIVE 运行时,它似乎会无限递归。
  • 我的立场是正确的;我错误地执行了您的建议。这似乎确实做到了!谢谢。
  • @AlexBalashov:添加了缺少的RECURSIVE 子句。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-07-03
  • 1970-01-01
  • 2020-12-17
  • 2016-06-18
  • 1970-01-01
  • 1970-01-01
  • 2012-10-28
相关资源
最近更新 更多