使用公用表表达式和IF EXISTS

时间:2017-05-29 15:30:21

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

我正在运行类似于

的查询
DECLARE @VARIABLE NVARCHAR(50) = 'VALUE';

WITH MYCTE_TABLE (Column1,Column2)
AS 
    SELECT 
        (ColumnA, Column B 
    FROM 
        SomeTable 
    WHERE 
        ColumnA = SomeValue)

    IF EXISTS(SELECT ColumnZ FROM AnotherTable WHERE Columnz = SomeNumbers)
    BEGIN
        SELECT * FROM MYCTE_TABLE
    END
    ELSE
    BEGIN
        MYSUBQUERY2
    END
...

但是,我一直收到以下错误:

  

关键字“IF”附近的语法不正确。

每个子查询在独立运行时运行良好。似乎在IF EXISTS之前使用公用表表达式导致问题。

请帮忙吗?

2 个答案:

答案 0 :(得分:2)

我真的怀疑,这是最好的方法......你试图清理并缩短它以获得brevitiy(对此赞不绝口!),但给定的信息是 - 可能 - 还不够。

您不能在不同的查询中使用CTECTE作为查询的一部分完全内联...

但是你可以将你的值写入一个像这里的表变量:

DECLARE @tbl TABLE(Column1 INT, Column2 VARCHAR(100)); --Choose appropriate types
INSERT INTO @tbl  
SELECT ColumnA, ColumnB FROM SomeTable WHERE ColumnA=SomeValue;

此表变量可以在以后的查询中使用(但在同一个作业中!),就像任何其他表一样:

SELECT *
FROM SomeTable AS st
INNER JOIN @tbl AS tbl ON ...

......或类似的用法...

另一种方法可能是这个

SELECT Column1,Column2 INTO #SomeTempTable FROM SomeWhere

这会将SELECT的结果写入临时表(会话范围)。

我很确定,可能有更好的(基于集合的)方法......两个子查询在结果集的结构中是否相同?如果是,您可以使用UNION ALL并将“IF EXISTS”作为WHERE - 子句放到每个子查询中。

答案 1 :(得分:1)

IF是控制流程。 WITH位于查询中。你可以这样做:

IF EXISTS (SELECT ColumnZ FROM AnotherTable WHERE Columnz=SomeNumbers)
BEGIN
    WITH MYCTE_TABLE (Column1,Column2)AS 
        SELECT (ColumnA, Column B FROM SomeTable WHERE ColumnA=SomeValue)
    MYSUBQUERY1
END;
ELSE
BEGIN
    WITH MYCTE_TABLE (Column1,Column2)AS 
        SELECT (ColumnA, Column B FROM SomeTable WHERE ColumnA=SomeValue)
    MYSUBQUERY2
END;

或者您可以使用临时表或表变量来存储值。