在SQL查询中使用变量的好方法是什么?

时间:2014-01-10 10:31:08

标签: sql-server tsql

我有以下代码:

SELECT
  A.ID,
  CASE
    WHEN A.AGE < 21 THEN 'MINOR'
    ELSE 'ADULT'
  END as CATEGORY

FROM PEOPLE as A

INNER JOIN OTHERPEOPLE as B on B.STUFF = A.CATEGORY

上面的代码不起作用,因为A.CATEGORY不是PEOPLE表中的有效列,但是我想以某种方式在连接中重用CATEGORY,而不再使用CASE语句。

那应该是可能的,对吧?

谢谢!

LE:我应该提一下,我正在寻找一种能够很好地处理大量数据的解决方案。我在这里给出的代码只是一个基本的模型。

5 个答案:

答案 0 :(得分:3)

子查询的替代方法是SQL Server中的Common Table Expression。它实际上与子查询相同,但您可以以更好的格式进行布局,以便更容易阅读。

你的例子就是这样:

;WITH PeopleExtended AS
(
    SELECT
        A.ID,
        CASE
            WHEN A.AGE < 21 THEN 'MINOR'
            ELSE 'ADULT'
        END as CATEGORY
    FROM
        PEOPLE AS A
)
SELECT
    *
FROM
    PeopleExtended AS A
    INNER JOIN OTHERPEOPLE AS B ON B.STUFF = A.CATEGORY

答案 1 :(得分:1)

您应该尝试子查询:

SELECT * FROM (
    SELECT
      A.ID,
      CASE WHEN A.AGE < 21 THEN 'MINOR' ELSE 'ADULT' END as CATEGORY
    FROM PEOPLE as A
) SUBQUERY,
INNER JOIN OTHERPEOPLE as B on B.STUFF = SUBQUERY.CATEGORY

答案 2 :(得分:1)

我想补充一点:如果你通过CTE方法获得所需的性能,请使用它。 CTE的模块化和记忆方面非常吸引人。如果不是:

  1. 使用minimally logged SELECT ... INTO
  2. 创建本地临时表
  3. 添加索引
  4. 在外部查询中使用本地临时表
  5. SELECT
      A.ID,
      CASE
        WHEN A.AGE < 21 THEN 'MINOR'
        ELSE 'ADULT'
      END as CATEGORY
    INTO #MyCategory
    FROM PEOPLE as A;
    
    CREATE UNIQUE CLUSTERED INDEX idx_MyCategory ON #MyCategory(ID, CATEGORY); 
    GO
    
    SELECT A.ID, A.CATEGORY
    FROM #MyCategory as A
    INNER JOIN OTHERPEOPLE as B on B.STUFF = A.CATEGORY;
    GO
    

    根据“真实”查询的实际复杂程度,数据规模以及可用的硬件资源,一种方法将比另一种方法表现更好。

    如果你有能力花时间,尝试多种方法并比较执行计划总是一个好主意。

    有关详细信息和见解,我强烈推荐本书第7章:

    Inside Microsoft® SQL Server® 2008: T-SQL Programming

答案 3 :(得分:0)

您需要使用子查询来使用它,如下所示

SELECT * FROM 
(
   SELECT  A.ID, CASE WHEN A.AGE < 21 THEN 'MINOR' ELSE 'ADULT' END as CATEGORY
   FROM PEOPLE as A
) t1
INNER JOIN OTHERPEOPLE as B on B.STUFF = t1.CATEGORY

答案 4 :(得分:0)

或使用CROSS APPLY

SELECT
    A.ID,
    CAT.CATEGORY

FROM PEOPLE as A
CROSS APPLY (SELECT 
             CASE WHEN AT.AGE < 21 THEN 'MINOR' ELSE 'ADULT' END as CATEGORY) CAT
INNER JOIN OTHERPEOPLE as B on B.STUFF = CAT.CATEGORY