递归CTE获取第一项

时间:2014-01-21 20:02:26

标签: sql sql-server database-design recursion

我的问题可能是我正在使用的表格的结构,我愿意接受任何建议。我有以下四个表,这些表被设置为允许公司有一组问题,每个问题有多个答案。问题的流程由所选的特定AnswerID决定。因此,根据个人如何回答问题,他/她可以根据每个答案被引导到不同的问题。

我当前的问题是我需要能够在层次结构中获得第一个问题。我试图通过递归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

2 个答案:

答案 0 :(得分:0)

我建议您将递归改为 DOWN 而不是 UP 只需修改CompanyAnswer表以包含PreviousQuestionID而不是{ {1}}

NextQuestionID

这将帮助您始终通过

找到热门家长问题
create table CompanyAnswer
(
CompanyAnswerID int not null,
CompanyQuestionID int not null,
AnswerID int not null,
PreviousQuestionID int null,
)

如果你需要找到孩子,你可以让你的递归下降。

答案 1 :(得分:0)

你的逻辑没有错。只需确保您的数据没有周期。如果您需要检测它们,请阅读Tarjan算法或Dijkstra算法。 http://hansolav.net/sql/graphs.html是在SQL中使用图形的一个很好的起点。