树具有递归和默认

时间:2015-04-14 12:24:58

标签: sql postgresql greatest-n-per-group common-table-expression recursive-query

使用Postgres。

我有pricelists

CREATE TABLE pricelists(
  id SERIAL PRIMARY KEY,
  name TEXT,
  parent_id INTEGER REFERENCES pricelists
);

和另一个表prices,引用它

CREATE TABLE prices(
  pricelist_id INTEGER REFERENCES pricelists,
  name TEXT,
  value INTEGER NOT NULL,
  PRIMARY KEY (pricelist_id, name)
);
  • 父价格表id=1可能有10个价格。
  • 作为父母id=2的孩子的价目表1可能有5个价格,这些价格会覆盖相同价格名称的父1价格。
  • 儿童价目表id=3与价格表2的孩子一样可能有2个价格会覆盖相同价格名称的子2价格。

因此,当我要求孩子3价格时,我想得到

  • 儿童3
  • 的所有价格
  • 他的父母(孩子2)的价格在子3
  • 中不存在
  • 到目前为止尚未存在的所有父1价格。

可以更改架构以提高效率。

实施例

如果

SELECT pl.id AS id, pl.parent_id AS parent, p.name AS price_name, value
FROM pricelists pl
JOIN prices p ON pl.id = p.pricelist_id;

给出

| id       |      parent   |  price_name |     value   |  
|----------|:-------------:|------------:|------------:|  
| 1        |  1            | bb          |     10      |  
| 1        |  1            | cc          |     10      |  
| 2        |  1            | aa          |     20      |  
| 2        |  1            | bb          |     20      |  
| 3        |  2            | aa          |     30      |

然后我正在寻找一种方法来获取pricelist_id = 3价格给我的价格

| id       |      parent   |  price_name |     value   |  
|----------|:-------------:|------------:|------------:|  
| 1        |  1            | cc          |     10      |  
| 2        |  1            | bb          |     20      |  
| 3        |  2            | aa          |     30      |

1 个答案:

答案 0 :(得分:1)

WITH RECURSIVE cte AS (
   SELECT id, name, parent_id, 1 AS lvl
   FROM   pricelists
   WHERE  id = 3  -- provide your id here

   UNION ALL
   SELECT pl.id, pl.name, pl.parent_id, c.lvl + 1
   FROM   cte  c
   JOIN   pricelists pl ON pl.id = c.parent_id
   )
SELECT DISTINCT ON (p.price_name)
       c.id, c.parent_id, p.price_name, p.value
FROM   cte c
JOIN   prices p ON p.pricelist_id = c.id
ORDER  BY p.price_name, c.lvl;  -- lower lvl beats higher level
相关问题