从分层表SQL中按关系顺序选择所有祖先

时间:2014-05-01 17:21:43

标签: sql sql-server

我在SQL Server的同一个表中使用父子关系这样的表

Finished Product|   Quantity           Unit                Bill Of Material
----------------------------------------------------------------------------------------
Product 1             1                 Nos                    Product 2
Product 1             1                 Nos                    Product 3
Product 1             1                 Nos                    Product 4
Product 2             2                 Nos                    Product 5
Product 2             1                 Nos                    Product 6
Product 2             3                 Nos                    Product 7
Product 2             1                 Nos                    Product 8
Product 3             3                 Nos                    Product 9
Product 3             2                 Nos                    Product 10
Product 3             1                 Nos                    Product 5
Product 3             1                 Nos                    Product 6
Product 4             2                 Nos                    Product 5
Product 4             2                 Nos                    Product 7
Product 4             2                 Nos                    Product 8
Product 5             2                 Nos                    Product 6
Product 5             3                 Nos                    Product 7
Product 5             4                 Nos                    Product 11
Product 5             2                 Nos                    Product 12

所以当我检查材料"产品6"如何与最终产品相关"产品1"我必须按照以下顺序获取表格。


      Quantity  Unit        Reference Item
        --------------------------------------------
        6           Nos      Product 5
        1           Nos      Product 3
        1           Nos      Product 2

自"产品6"没有直接连接到"产品1"但通过"产品1和#34;间接连接;子。

为什么结果表包含6个No"产品5"是"产品6"连接到"产品1"低谷"产品5"以3种不同的方式。我们需要2个"产品6"对于每个"产品5" 即

Product 1 ---- Product 2 ---- Product 5 ---- product 6.<br/>
Product 1 ---- Product 3 ---- Product 5 ---- Product 6.<br/>
Product 1 ---- Product 4 ---- Product 5 ---- product 6.<br/>

以上序列仅考虑&#34;产品5&#34;关系。

2 个答案:

答案 0 :(得分:0)

您可以使用递归CTE。对于与成品1相关的所有可能行,将@Material设置为NULL。同样,要查看材料Product 6的所有行,请将@FinishedProduct设置为NULL。

-- Create CTE  
DECLARE @Material VARCHAR(50) = 'Product 6',  
@FinishedProduct VARCHAR(50) = 'Product 1'  

;WITH   recursiveProduct  
AS   
(  
   -- Generate component level line, effectively where "parent" is null  
    SELECT  p1.Material,  
            CAST(( p1.FinishedProduct + ' --- ' + p1.Material ) AS VARCHAR(MAX)) FinishedProductList,  
            p1.FinishedProduct  
    FROM    dbo.Products p0  
    RIGHT JOIN dbo.Products p1 ON p0.FinishedProduct = p1.Material  
    WHERE   p0.Material IS NULL AND COALESCE(@Material,p1.Material) = p1.Material  

   UNION ALL

    -- Now the recursive bit
   SELECT   p2.Material,  
            CAST(( p2.FinishedProduct + ' --- ' + rp.FinishedProductList ) AS VARCHAR(MAX)) FinishedProductList,
            p2.FinishedProduct  
   FROM     recursiveProduct rp JOIN dbo.Products p2 ON rp.FinishedProduct = p2.Material  
 )  
-- Select data of interest  
SELECT FinishedProductList FROM recursiveProduct WHERE COALESCE(@FinishedProduct, FinishedProduct) = FinishedProduct  

如果其他人想要编写更好的答案代码,这里是生成测试数据的代码。我假设该单位在这个问题上是无关紧要的。

IF OBJECT_ID('Products', 'U') IS NOT NULL  
    DROP TABLE Products  
GO  
CREATE TABLE Products 
( FinishedProduct VARCHAR(50) , Quantity INT , Material VARCHAR(50) )
GO
INSERT  dbo.Products
VALUES  ( 'Product 1', 1, 'Product 2' ),
        ( 'Product 1', 1, 'Product 3' ),
        ( 'Product 1', 1, 'Product 4' ),
        ( 'Product 2', 2, 'Product 5' ),
        ( 'Product 2', 1, 'Product 6' ),
        ( 'Product 2', 3, 'Product 7' ),
        ( 'Product 2', 1, 'Product 8' ),
        ( 'Product 3', 3, 'Product 9' ),
        ( 'Product 3', 2, 'Product 10' ),
        ( 'Product 3', 1, 'Product 5' ),
        ( 'Product 3', 1, 'Product 6' ),
        ( 'Product 4', 2, 'Product 5' ),
        ( 'Product 4', 2, 'Product 7' ),
        ( 'Product 4', 2, 'Product 8' ),
        ( 'Product 5', 2, 'Product 6' ),
        ( 'Product 5', 3, 'Product 7' ),
        ( 'Product 5', 4, 'Product 11' ),
        ( 'Product 5', 2, 'Product 12' )
GO  

答案 1 :(得分:0)

看看这篇文章是否有帮助......

通常可以添加邻接表来维护父级&gt;儿童和孩子 - &gt;父关系以获得更好的查询。

Select all parents or children in same table relation SQL Server