2014-08-21 41 views
3

我正在使用PostgreSQL 9.2。我有一个存储产品信息的产品表,其子表是包含与其链接的产品的内容表。在单个查询中分层检索记录

假设,例如,如果我有一个主表称为汉堡产品,那么我将有像

其内容 产品
bread,cheese,chilli. 

他们可以是一个场景,面包将成为主打产品,其含量将面粉和盐等

我写一个查询与他们的内容产品检索(与之相关联的ID)的所有产品,应该是这样的层次结构

Burger----bread--+----flour 
       +----salt 
     ----cheese 
     ----chilli 
显示的东西

我一定要得到的结果是这样

burger bread 
burger cheese 
burger chilli 
bread flour 
bread salt 

这种层次结构可以运行多达N个级别(如平坦的地板可以在这种情况下,子内容用它,它应该是这样的

burger bread 
burger cheese 
burger chilli 
bread flour 
bread salt 
flour someprod1 
flour someprod2 assuming if someprod1 and someprod2 are the contents) 

我写了下面的查询:

select rec.m_product_id,rec.m_productbom_id 
from rec_product_recipe rec 
join rec_product_recipe rec1 
on rec1.m_productbom_id = rec.m_product_id 

但这最多可显示自己作为一个级别:

burger bread 
burger cheese 
burger chilli 
+0

我认为这个问题会在StackOverflow或DBA上做得更好。无论哪种方式,你是否尝试过递归CTE?如果不看[文档](http://www.postgresql.org/docs/8.4/static/queries-with.html)中的'WITH RECURSIVE'语句。 – 2014-09-03 16:50:21

+0

表格定义和一些示例值将非常赞赏,像这样的问题。 – 2014-09-03 21:49:58

回答

0

这是一个recursive CTE一个典型例子:

WITH RECURSIVE cte AS (
    SELECT 0 AS lvl, m_product_id, m_productbom_id 
    FROM rec_product_recipe 
    WHERE m_product_id = <id of burger> -- restrict to one root product 

    UNION ALL 
    SELECT c.lvl + 1, r.m_product_id, r.m_productbom_id 
    FROM cte c 
    JOIN rec_product_recipe r ON r.m_product_id = c.m_productbom_id 
    -- WHERE c.lvl < 10 -- protection against loops (optional) 
    ) 
SELECT * 
FROM cte 
ORDER BY 1,2,3; 

就像这样:

如果你循环依赖查询将被卡住在无尽的循环中,并最终引发异常。如果发生这种情况,请添加某种休息条件。就像我添加为注释的最大迭代级别一样。或者外部SELECTLIMIT n,这也使CTE一旦检索到足够的行就停止循环。 Examples in the manual