我有两个基本实体:财务计划和购买请求。 Theese两个实体处于多对多的关系中:
CREATE TABLE FinancialPlan
(
ID int NOT NULL,
PRIMARY KEY (ID)
);
CREATE TABLE PurchaseRequest
(
ID int NOT NULL,
PRIMARY KEY (ID)
);
CREATE TABLE FP_PR
(
FP_ID FOREIGN KEY REFERENCES FinancialPlan(ID),
PR_ID FOREIGN KEY REFERENCES PurchaseRequest(ID)
);
问题:查找与指定计划相关的所有请求以及与指定计划相关的所有与请求相关的计划,...
模型可以表示为图形,其中每个节点代表一个计划或一个请求,每个边代表一个关系,然后问题可以改为查找连接组件,指定节点属于
示例:
Plan Request FP_PR
ID | ID | FP_ID|PR_ID|
----| ----| -----|-----|
1 | 1 | 1 |1 |
2 | 2 | 2 |1 |
3 | 3 | 2 |2 |
4 | 3 |2 |
5 | 4 |2 |
5 |3 |
查找finplan ID = 1
的连通分量期望的输出:
FP_ID | PR_ID|
------+------+
1 | 1 |
2 | 1 |
2 | 2 |
3 | 2 |
4 | 2 |
我目前正在app端递归执行,这可能会生成许多请求并挂起数据库服务器,这可以通过一些递归数据库方法完成吗?
答案 0 :(得分:1)
SQL Server解决方案
我想主要问题是您需要按PR_ID
然后FP_ID
进行比较。因此在递归部分必须有CASE
语句。在1次运行中,我们在FP_ID
之后以PR_ID
等方式获取数据,并借助模数。
DECLARE @fp int = 1
;WITH cte AS (
SELECT f.FP_ID,
f.PR_ID,
1 as lev
FROM #FP_PR f
WHERE f.FP_id = @fp
UNION ALL
SELECT f.FP_ID,
f.PR_ID,
lev+1
FROM cte c
CROSS JOIN #FP_PR f -- You can use INNER JOIN instead
WHERE CASE (lev+1)%2 WHEN 0 THEN f.PR_ID WHEN 1 THEN f.FP_ID END = CASE (lev+1)%2 WHEN 0 THEN c.PR_ID WHEN 1 THEN c.FP_ID END
AND NOT (f.PR_ID = c.PR_ID AND f.FP_ID = c.FP_ID)
)
SELECT *
FROM cte
输出:
FP_ID PR_ID lev
1 1 1
2 1 2
2 2 3
3 2 4
4 2 4