SQL检索所有链接的记录

时间:2018-06-11 12:40:22

标签: sql sql-server

我有一个产品表(tProduct)和一个产品链接表(tProductLink),以便在产品之间建立链接。给定ProductID和ProductLinkID,我需要获取所有相关的tProduct.ID记录。

在下面的示例表(tProductLink)中,将返回所有ID。请注意,无法创建递归链接;在下表中给出第一行的情况下,不能有ProductID为31563且ProductID为28818的行。

所以说我搜索与第4行,ProductID 137902和LinkProductID 410901中的链接相关的所有产品。给该链接,它应该返回所有六行。

以下是数据的示例。

Table Examples.
我尝试了各种技术,如递归CTE和使用“交叉应用”调用表函数,但我无处可去。

这是我尝试过的最后一个解决方案之一,最终没有按照评论中的说明退回所有产品。

declare @ProductID int, @ProductLinkID int
select @ProductID = 137902
select @ProductLinkID = 410901

;with p1 as
(
     select ProductID, ProductLinkID
     from tProductLink
     where ProductID = @ProductID and ProductLinkID = @ProductLinkID
     union all
     select tProductLink.ProductID, tProductLink.ProductLinkID
     from tProductLink
     join p1 on p1.ProductLinkID = tProductLink.ProductID
     where not (tProductLink.ProductID = @ProductID and tProductLink.ProductLinkID = @ProductLinkID)
)
select distinct ProductID from p1
union
select ProductLinkID from p1

1 个答案:

答案 0 :(得分:1)

您从一个ID开始。这可以在第二个表中的多行ProductLinkIdProductId中。您可以在第二个表中再次查找相应的ID。

这会要求递归查询,您始终可以收集所有相应的ID。不幸的是,SQL Server在递归查询中不支持DISTINCT,因此会多次查找相同的ID。 SQL Server也不会阻止循环(但是会失败),因此我们必须通过记住已经找到的ID来防止它们。理想情况下,这将使用我们填充的数组或集合来完成,但SQL Server不支持这样做,因此我们必须构建一个字符串。

完整的查询:

with cte(id, seen) as
(
  select 28520 as id, cast('/28520/' as varchar(max)) as seen from t1
  union all
  select case when cte.id = t2.productid then t2.linkproductid 
                                         else t2.productid end as id,
    cte.seen + cast(case when cte.id = t2.productid 
                      then t2.linkproductid 
                      else t2.productid end as varchar(max)) + '/'
  from cte
  join t2 on cte.id in (t2.productid, t2.linkproductid) 
    and charindex('/' + cast(case when cte.id = t2.productid
                               then t2.linkproductid
                               else t2.productid end as varchar(max))+ '/', cte.seen) = 0
)
select distinct id from cte
option (maxrecursion 1000);

Rextester演示:http://rextester.com/WJJ78304