在投影内声明变量

时间:2013-05-15 18:19:08

标签: sql sql-server sql-server-2008 tsql

请注意,我需要声明一个变量,这是另一个查询的结果。如果不这样做,我需要在需要值的任何时候重复此查询。

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关键字,但它没有成功

1 个答案:

答案 0 :(得分:7)

你不需要那么疯狂。你想要做的事情有很多概念上的问题。

  1. 您无法在查询中声明变量。

  2. 标量变量只能包含一个值。

  3. SQL Server中的标量变量始终以@开头。游标变量可以是普通标识符,但你绝对不需要游标。

  4. 一个简单的JOIN会做你想要的。子查询方法有效,但很难(在SELECT语句中坚持查询),不能提取多个列值,并且不能像JOIN那样在整个查询中重复使用。

  5. 您可以直接在列上使用CASE语句。没有必要首先尝试将值放入变量中。无论如何这都行不通(见#2)。

  6. 您可以使用IsNullCoalesce函数将NULL变为0,语法更简单。

  7. 我建议您使用提示表格的别名,而不是使用AB。例如,SStudentsOOverwrittenScores

  8. 考虑到所有这些要点,你可以做这样的事情:

    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} }})。我建议这样做是因为它可以帮助您更快地理解连接,因为您已经知道本地表并且想知道外部表,因此您的眼睛不必扫描到目前为止。我还建议在单独的行上放置多个条件。我保证,如果你养成这样做的习惯,你将来能够更快地理解自己的查询。