2014-01-21 81 views
0

我的問題可能是我正在使用的表的結構,我對任何建議都開放。我有以下四個表格,這些表格是爲了讓一個公司有一組問題而設立的,每個問題都有多個答案。問題的流程由所選的特定AnswerID決定。因此,根據個人如何回答問題,他/她可以根據每個答案指向不同的問題。遞歸CTE獲取第一項

我目前的問題是,我需要能夠得到層次結構中的第一個問題。我試圖用遞歸CTE實現這一點,但不相信我已經正確設置了它(或者甚至可能由於表結構),因爲我收到了最大遞歸錯誤並且通過選項(maxrecursion 0)抑制了最大值沒有幫助,因爲它似乎沒有完成。我假設這是因爲它自己加入的CTE部分返回了多行。請參閱下面的內容,瞭解我目前的功能。

create table Company 
(
    CompanyID int not null, 
    constraint pk_Company primary key (CompanyID) 
) 

create table Question 
(
    QuestionID int not null, 
    QuestionText varchar(250) not null, 
    constraint pk_Question primary key (QuestionID) 
) 

create table Answer 
(
    AnswerID int not null, 
    AnswerText varchar(250) not null, 
    constraint pk_Answer primary key (AnswerID) 
) 

create table CompanyQuestion 
(
    CompanyQuestionID int not null, 
    CompanyID int not null, 
    QuestionID int not null, 
    constraint pk_CompanyQuestion primary key (CompanyQuestionID), 
    constraint fk_CompanyQuestion_Company foreign key (CompanyID) references Company (CompanyID), 
    constraint fk_CompanyQuestion_Question foreign key (QuestionID) references Question (QuestionID) 
) 

create table CompanyAnswer 
(
    CompanyAnswerID int not null, 
    CompanyQuestionID int not null, 
    AnswerID int not null, 
    NextQuestionID int null, 
    constraint pk_CompanyAnswer primary key (CompanyAnswerID), 
    constraint fk_CompanyAnswer_CompanyQuestion foreign key (CompanyQuestionID) references CompanyQuestion (CompanyQuestionID), 
    constraint fk_CompanyAnswer_Answer foreign key (AnswerID) references Answer (AnswerID), 
    constraint fk_CompanyAnswer_NextQuestion foreing key (NextQuestionID) references CompanyQuestion (CompanyQuestionID) 
) 

with cte (CompanyQuestionID, NextQuestionID, Tier) 
as 
(
    select a.CompanyQuestionID, 
      a.NextQuestionID, 
      0 as 'Tier' 
    from CompanyAnswer a 
    where a.NextQuestionID is null 

    union all 

    select a.CompanyQuestionID, 
      a.NextQuestionID, 
      "Tier" + 1 
    from CompanyAnswer a 
    join cte 
     on a.NextQuestionID = cte.CompanyQuestionID 
    where a.NextQuestionID is not null 
) 

select CompanyQuestionID, 
     NextQuestionID, 
     Tier 
from cte 
+0

只是爲了測試,將其更改爲'where a.NextQuestionID不爲null且[Tier] <= 10'這是否仍然會引發maxrecursion錯誤? – Anon

+0

當我這樣做的時候它確實有效,但我不相信那會給我我要找的答案嗎?我不是在尋找最高層來獲得第一個問題嗎? –

+3

鑑於它在您關閉時可以正常工作,您確定您的數據沒有周期嗎?即Q1-> Q2-> Q3-> Q1。如果有周期,那麼你沒有'最高層' – Anon

回答

0

你的邏輯沒有錯。只要確保你的數據沒有周期。如果您需要檢測它們,請閱讀Tarjan算法或Dijkstra算法。 http://hansolav.net/sql/graphs.html是在SQL中使用圖表的一個很好的起點。

+0

謝謝你的鏈接。我今晚會讀到這個。 –

0

我會建議你改變你的遞歸去的DOWN代替UP只需修改CompanyAnswer表包括PreviousQuestionID代替NextQuestionID

create table CompanyAnswer 
(
CompanyAnswerID int not null, 
CompanyQuestionID int not null, 
AnswerID int not null, 
PreviousQuestionID int null, 
) 

這將幫助你總能找到頂部問題提問者:

Select * from CompanyAnswer Where PreviousQuestionID is null 

,如果你需要找到孩子,你可以讓你的遞歸下降。

+0

謝謝你的建議;我不認爲我能夠完全刪除NextQuestionID,因爲我需要知道下一個問題是基於所選答案的。我最近在設計中確實有過PreviousQuestionID列,但認爲如果更新了CompanyAnswer的Ne​​xtQuestionID實例,將很難維護,因爲我必須查詢/更新其他CompanyAnswers PreviousQuestionID值才能正確地反映此更改。 –