0

我有兩個表,一個是產品客戶映射,另一個是產品共享表。使用SQL遞歸CTE,在給定產品的情況下,我試圖找到所有鏈接爲鏈的產品,並映射到客戶之間。另外,如果產品與其他產品共享,我也需要將其包含在鏈中。希望我的例子更有意義比描述使用兩個表的SQL遞歸CTE

Product Customer Table 
Product Customer 
    Milk  Illinois 
    Milk  Michigan 
    Butter Michigan 
    Cream Wisconsin 
    Honey Wisconsin 
    Cheese Minnesota 

Product Sharing Table 
Product SharedProduct 
Butter  Cream 
Cream  Cheese 

對於上述數據,假設我輸入的是牛奶,然後將結果集應包括所有的產品 - 牛奶,黃油,奶油,蜂蜜&奶酪。在這裏黃油奶油&奶油芝士通過產品共享錶鏈接。

我目前的SQL看起來像這樣,但實際上並沒有超過一個級別的工作。

WITH Product_CTE AS 
(
    SELECT DISTINCT [Product] FROM ProductCustomer 
    WHERE [Product] IN (SELECT DISTINCT p2.[Product] 
    FROM ProductCustomer p1 INNER JOIN ProductCustomer p2 
    ON p1.[Customer] = p2.[Customer] WHERE p1.[Product] = 'Milk') 
    UNION ALL 
    SELECT [SharedProduct] FROM ProductSharing b 
    INNER JOIN Product_CTE p ON p.[Product] = b.[Product] 
) 
Select [Product] from Product_CTE 
+0

只是爲了澄清,你的例子來自'親愛的':牛奶>密歇根州>黃油>奶油(通過分享)>威斯康星州>蜂蜜。是對的嗎? – HABO

+0

是的,這是正確的。 – user320587

回答

0

一個CTE有多個UNION s的問題。雖然可能,但它不適合我。

另一種方法是使用循環時,有沒有更多的行添加到工作臺上時停止:

declare @ProductCustomers as Table (Product VarChar(16), Customer VarChar(16)) 
insert into @ProductCustomers (Product, Customer) values 
    ('Milk', 'Illinois'), 
    ('Milk', 'Michigan '), 
    ('Butter', 'Michigan '), 
    ('Cream', 'Wisconsin'), 
    ('Honey', 'Wisconsin'), 
    ('Cheese', 'Minnesota') 

declare @ProductSharing as Table (Product VarChar(16), SharedProduct VarChar(16)) 
insert into @ProductSharing (Product, SharedProduct) values 
    ('Butter', 'Cream '), 
    ('Cream', 'Cheese ') 

declare @TargetProduct as VarChar(16) = 'Milk' 

declare @ProductChain as Table (Product VarChar(16)) 
insert into @ProductChain (Product) values (@TargetProduct) 
declare @NewRows as Int = 1 

while @NewRows > 0 
    begin 
    set @NewRows = 0 
    -- Add products shared by the same customer. 
    insert into @ProductChain 
    select PCR.Product 
     from @ProductCustomers as PCL inner join 
     @ProductCustomers as PCR on 
      -- Shared customer. 
      PCR.Customer = PCL.Customer and 
      -- Different product. 
      PCR.Product <> PCL.Product 
     where not exists (select 42 from @ProductChain where Product = PCR.Product) 
    set @NewRows = @NewRows + @@RowCount 
    -- Add products linked through the product sharing table. 
    insert into @ProductChain 
    select PS.SharedProduct 
     from @ProductSharing as PS inner join 
     @ProductChain as PC on PC.Product = PS.Product 
     where not exists (select 42 from @ProductChain where Product = PS.SharedProduct) 
    set @NewRows = @NewRows + @@RowCount 
    end 

select Product 
    from @ProductChain 
    order by Product 

這裏假設的是,@ProductSharing表是單向的。

+0

謝謝你的代碼。看起來我無法在單個查詢中做到這一點。因爲,我需要從JAVA執行這個查詢,所以我可能需要將它作爲SP。再次感謝。 – user320587