注意:我的研究出现了this question,这为我的问题提供了一个可能的解决方案,但我的问题更为笼统:我应该采用哪种解决方案?
我想查询一个学术历史数据库,给我一个特定学生所采取的每对微积分课程的记录,其中一个是另一个的先决条件。如果数据库设置得很好或者课程编号合理,我可以这样做:
SELECT ...
FROM Academic_History PrerequisiteCourse
JOIN Academic_History NextCourse
ON (NextCourse.CalculusLevel = PrerequisiteCourse.CalculusLevel + 1)
WHERE ...
当然,CalculusLevel字段不存在,所以这是无稽之谈。此外,有几个课程编号可以作为微积分I,有几个可以作为微积分II,等等,这些经常变化。这使得将所有先决条件配对硬编码到JOIN语句中,这是一个非常糟糕的主意:
SELECT ...
FROM Academic_History PrerequisiteCourse
JOIN Academic_History NextCourse
ON (NextCourse.CourseNumber = '231' AND PrerequisiteCourse.CourseNumber = '220'
OR NextCourse.CourseNumber = '231' AND PrerequisiteCourse.CourseNumber = '221'
OR NextCourse.CourseNumber = '241' AND PrerequisiteCourse.CourseNumber = '231'
OR NextCourse.CourseNumber = '24-' AND PrerequisiteCourse.CourseNumber = '231'
...)
WHERE ...
我应该做的事情是动态创建我的“CalculusLevel”字段,这将更容易维护:
SELECT CASE PrerequisiteCourse.CRS_NBR
WHEN '115' THEN '0'
WHEN '220' THEN '1'
WHEN '221' THEN '1'
...
END PrerequisiteCourseLevel,
CASE NextCourse.CRS_NBR
WHEN '115' THEN '0'
WHEN '220' THEN '1'
WHEN '221' THEN '1'
...
END NextCourseLevel,
FROM Academic_History PrerequisiteCourse
JOIN Academic_History NextCourse
ON (PrerequisiteCourseLevel + 1 = NextCourseLevel)
WHERE ...
但是当然连接不起作用,因为那些列不在那些表中。即使我将条件移出JOIN ON
并进入WHERE
子句,但我得到一个“无效标识符”错误,可能是因为当WHERE子句正在存在时这些字段还不存在执行。
这样做的正确方法是什么?我想出了一些像我在第二个代码块中提到的那样的解决方案,但他们都觉得不专业的黑客攻击。
谢谢!
答案 0 :(得分:2)
您可以使用CTE添加可重复使用的列:
;with hist as
(
select case ... end as NextCourseLevel
, case ... end as PrerequisiteCourseLevel
, *
from Academic_History
)
select *
from hist t1
join hist t2
on t1.PrerequisiteCourseLevel + 1 = t2.NextCourseLevel
编辑:根据您的评论,您可以通过在任何地方展开它来重构with
语句:
select *
from (
select case ... end as PrerequisiteCourseLevel
, *
from Academic_History
) as t1
join (
select case ... end as NextCourseLevel
, *
from Academic_History
) as t2
on t1.PrerequisiteCourseLevel + 1 = t2.NextCourseLevel