请注意,我需要声明一个变量,这是另一个查询的结果。如果不这样做,我需要在需要值的任何时候重复此查询。
SQL Server抛出一个例外,即不在DECLARE
关键字内写SELECT
。我能做什么或者我缺少什么?
SELECT A.StudentId,
(
CASE WHEN (SELECT B.OverwrittenScore
FROM dbo.OverwrittenScores AS B
WHERE B.StudentId = A.StudentId AND B.AssignmentId = @assignmentId) IS NOT NULL
THEN (SELECT B.OverwrittenScore
FROM dbo.OverwrittenScores AS B
WHERE B.StudentId = A.StudentId AND B.AssignmentId = @assignmentId)
ELSE (-- ANOTHER QUERY, BY THE MOMENT: SELECT 0
) END
) AS FinalScore
FROM dbo.Students AS A
在括号内我需要实现一些逻辑,我的意思是可能实现另外两个查询。 我在想,如果在这里我可以使用BEGIN关键字,但它没有成功
答案 0 :(得分:7)
你不需要那么疯狂。你想要做的事情有很多概念上的问题。
您无法在查询中声明变量。
标量变量只能包含一个值。
SQL Server中的标量变量始终以@
开头。游标变量可以是普通标识符,但你绝对不需要游标。
一个简单的JOIN
会做你想要的。子查询方法有效,但很难(在SELECT
语句中坚持查询),不能提取多个列值,并且不能像JOIN
那样在整个查询中重复使用。
您可以直接在列上使用CASE
语句。没有必要首先尝试将值放入变量中。无论如何这都行不通(见#2)。
您可以使用IsNull
或Coalesce
函数将NULL
变为0
,语法更简单。
我建议您使用提示表格的别名,而不是使用A
和B
。例如,S
为Students
,O
为OverwrittenScores
。
考虑到所有这些要点,你可以做这样的事情:
SELECT
S.StudentId,
OverwrittenScore = Coalesce(O.OverwrittenScore, 0)
FROM
dbo.Students S
LEFT JOIN dbo.OverwrittenScores O
ON S.StudentId = O.StudentID
AND O.AssignmentId = @assignmentId
LEFT JOIN dbo.SomeOtherTable T -- add another join here if you like
ON S.StudentID = T.StudentID
AND O.OverwrittenScore IS NULL
<强>更新强>
我在上面为你添加了另一个LEFT JOIN
。你看到它在O.OverwrittenScore IS NULL
的条件下如何加入?在我看来,它可能会做你想要的。
同样,如果您提供更多细节,我会向您展示更多答案。
此外,对于它的价值,您对帖子的编辑过于复杂。如果你打算以这种方式编写查询,那就更好了:
SELECT
S.StudentId,
FinalScore =
Coalesce(
(SELECT O.OverwrittenScore
FROM dbo.OverwrittenScores O
WHERE
S.StudentId = O.StudentId
AND O.AssignmentId = @assignmentId
),
(SELECT SomethingElse FROM SomewhereElse),
0
)
FROM dbo.Students S
我还鼓励您在编写关联或联接时将其他或外部表放在联接中(如S.StudentId = O.StudentId
而不是{{1} }})。我建议这样做是因为它可以帮助您更快地理解连接,因为您已经知道本地表并且想知道外部表,因此您的眼睛不必扫描到目前为止。我还建议在单独的行上放置多个条件。我保证,如果你养成这样做的习惯,你将来能够更快地理解自己的查询。