我在sql server数据库中有一个表,其中存储了事务记录。表包含买方的用户ID和产品卖方的用户ID。我必须在表格中找到圆圈,例如 -
我必须得到类型的记录 - A卖给B,B卖给C,C卖给D和D卖给A。
请帮忙。
答案 0 :(得分:1)
使用以下功能:
CREATE FUNCTION dbo.CheckIsCircular(@SellerId INT)
RETURNS BIT
AS BEGIN
DECLARE @IsCircular BIT = 0
DECLARE @Sellers TABLE(Id INT)
DECLARE @TempSellers TABLE(Id INT)
DECLARE @Buyers TABLE(Id INT)
INSERT INTO @TempSellers(Id)VALUES(@SellerId)
WHILE EXISTS(SELECT * FROM @TempSellers)BEGIN
IF EXISTS(SELECT *
FROM @Sellers s
INNER JOIN @TempSellers t ON t.Id = s.Id)BEGIN
SET @IsCircular = 1
BREAK;
END
INSERT INTO @Sellers(Id)
SELECT Id FROM @TempSellers
INSERT INTO @Buyers(Id) SELECT BuyerId FROM YourTable
DELETE @TempSellers
INSERT Into @TempSellers(Id)
SELECT YourTable.SellerId
FROM YourTable
INNER JOIN @Buyers ON [@Buyers].Id = YourTable.SellerId
END
RETURN @IsCircular
END
答案 1 :(得分:0)
您的问题是图形遍历的挑战;这在SQL中本身不受支持,但您可以simulate it。
答案 2 :(得分:0)
这是我在Teradata中执行此操作的框架,因此必须对SQL Server稍微修改语法:
WITH RECURSIVE cte (..., Path, isCycle) AS
(
SELECT
...
,',' || CAST(seller AS VARCHAR(1000)) || ',' AS path
,0 AS isCycle
FROM tab
UNION ALL
SELECT
...
,cte.Path || cte.buyer || ',',
,case when cte.Path LIKE '%,' || TRIM(tab.buyer) || ',%' then 1 else 0 end
FROM cte, tab
WHERE cte.buyer = tab.seller
AND cte.isCycle <> 1
)
SELECT ...
,Path || Destination
,isCycle
FROM cte
WHERE isCycle = 1
在遍历时构建图表的物化路径,并检查下一个买家是否已经在此路径中。
答案 3 :(得分:-1)
使用递归cte
declare @trans table (seller int, buyer int)
insert @trans
values (1,2),(2,3),(3,4),(4,1),(1,5),(2,6),(3,5)
begin try
;with cte as
(
select *, convert(varchar(500),'') as route from @trans
union all
select cte.seller, t1.buyer, convert(varchar(500),route + CONVERT(varchar(5),t1.seller)) from cte
inner join @trans t1 on cte.buyer = t1.seller
)
select * from cte
where seller=buyer
option (maxrecursion 50)
end try
begin catch
print 'loops'
end catch