簡體   English   中英

SQL Server 查找類先決條件循環

[英]SQL Server Finding Class Prerequisites Loop

你好 Stack Overflow 的人們,

我被困在 SQL 作業的最后一個問題上,需要指導。

create table PREQUISITE (  
    Cno     varchar(9) REFERENCES COURSE(Cno), 
    Cpre    varchar(9) REFERENCES COURSE(Cno),
    primary key(Cno, Cpre)
);

我有這張表,具有以下值:

('MATH 1910', 'MATH 1730'),
('CSCI 1170', 'MATH 1730'),
('CSCI 2170', 'CSCI 1170'),
('CSCI 3080', 'CSCI 1170'),
('CSCI 3080', 'MATH 1910'),
('CSCI 3110', 'CSCI 2170'),
('CSCI 3110', 'CSCI 3080'),
('CSCI 3130', 'CSCI 2170'),
('CSCI 3210', 'CSCI 3110'),
('CSCI 3210', 'COMM 2200'),
('CSCI 3240', 'CSCI 2170'),
('CSCI 3240', 'CSCI 3130'),
('CSCI 4610', 'CSCI 3110'),
('CSCI 4610', 'CSCI 3130'),
('CSCI 4700', 'CSCI 3110'),
('CSCI 4700', 'COMM 2200');

我正在嘗試編寫一個帶有單個參數的函數,例如CSCI 4700 ,它返回一個包含所有類的先決條件的字符串,以及那些類的先決條件等等。 我曾嘗試使用滾動光標循環遍歷表格並重置回表格頂部以及 while exists 循環,但我不確定要遵循哪條路徑來生成此輸出:

CSCI 4700 -- CSCI 3110, COMM 2200 
CSCI 3110 --  CSCI 3080, 2170 
COMM 2200 -- no perquisite 
CSCI 3080 -- CSCI 1170, MATH 1910 
CSCI 2170 -- CSCI 1170 CSCI 1170 -- MATH 1730 
MATH 1910 -- MATH 1730  
MATH 1730 -- no prequisite

不是在這里尋找代碼中的答案,只是關於哪些 SQL 操作可以實現此目的的建議

以下查詢給出樹狀結構。 如果您有循環引用,查詢將掛起。 例如,此代碼不處理ALGEBRA -> MATH -> ALGEBRA情況。

 with src as ( select 1 as id, 3 as req_id union all select 2 as id, 5 as req_id union all select 3 as id, 4 as req_id union all select 4 as id, null as req_id union all select 4 as id, 2 as req_id union all select 5 as id, 6 as req_id union all select 6 as id, null as req_id ), q0 as ( select * from src where id = 1 ), q1(src, req, lvl) as ( select id, req_id, 0 from q0 union all select id, req_id, lvl + 1 from src inner join q1 on req = id ) select * from q1 GO
 來源 | 請求 | 等級——: |  ---: |  --: 1 |  3 |  0 3 |  4 |  1 4 | |  2 4 |  2 |  2 2 |  5 |  3 5 |  6 |  4 6 | |  5個

db<> 在這里擺弄

這是一個帶有一些字符串聚合的遞歸 CTE,可能會讓您對您的函數有所了解。

DECLARE @Cno VARCHAR(9);
DECLARE @CpreList VARCHAR(4000);
SET @Cno = 'CSCI 4700';

WITH RCTE AS
(
    SELECT Cno AS BaseCno, 0 AS Lvl, Cno, Cpre
    FROM PREQUISITE
    WHERE Cno = @Cno

    UNION ALL

    SELECT c.BaseCno, Lvl+1, t.Cno, t.Cpre
    FROM RCTE c
    JOIN PREQUISITE t ON t.Cno = c.Cpre
    WHERE t.Cno != c.BaseCno
)
SELECT @CpreList = STRING_AGG(Cpre, ', ') WITHIN GROUP (ORDER BY Cpre)
FROM (SELECT DISTINCT BaseCno AS Cno, Cpre FROM RCTE) q
GROUP BY Cno;

SELECT @CpreList AS CpreList;

退貨:

CpreList
COMM 2200, CSCI 1170, CSCI 2170, CSCI 3080, CSCI 3110, MATH 1730, MATH 1910

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM