使用SQL Server 2005“WITH”语句的多个选择语句

时间:2009-06-05 02:24:13

标签: sql-server-2005

我正在尝试在SQL Server 2005中使用“WITH”语句。如果我执行以下操作,它似乎工作正常:

WITH MyBigProducts AS (SELECT * FROM Products WHERE Size='Big')
SELECT Name FROM MyBigProducts

但如果我尝试使用多个选择语句,它会失败,如:

WITH MyBigProducts AS (SELECT * FROM Products WHERE Size='Big')
SELECT Name FROM MyBigProducts
SELECT Count(*) FROM MyBigProducts

,错误消息为“无效的对象名称'MyBigProducts'”。

我可以采取哪些措施来扩大“MyBigProducts”表的范围以包含两个select语句吗?

我的示例是导致问题的实际代码的简化,所以我并不打算上述简单示例应该工作的可能性以及我的SQL中还有另一个错误。

我尝试在两个SELECT语句周围包装一个BEGIN和END,但解析器无法编译它。

4 个答案:

答案 0 :(得分:14)

我相信公用表表达式仅对即时使用有效,这就是“SELECT Count(*)FROM MyBigProducts”出错的原因。为了重用CTE,您应该使用临时表

DECALRE @BigProducts TABLE (...[declaration omitted]...)

INSERT INTO @BigProducts
SELECT * 
FROM Products 
WHERE Size='Big'


SELECT Name FROM @BigProducts
SELECT Count(*) FROM @BigProducts

如果我错了,请纠正我。

答案 1 :(得分:14)

正如Kane所说,CTE仅在编写它的SQL语句中可用。根据您的具体情况,另一种可能的解决方案是在单个查询中包含COUNT(*):

;WITH MyBigProducts AS
(
     SELECT
          Name,
          COUNT(*) OVER () AS total_count
     FROM
          Products
     WHERE
          Size = 'Big'
)
SELECT
     Name,
     total_count
FROM
     MyBigProducts

答案 2 :(得分:2)

CTE具有声明本地范围和可见性。如果您想要更大的表空间范围和可见性,则需要将CTE设置为View或表值函数。

或者,您可以将表达式结果具体化为表变量,该表变量是当前批次的本地变量,或者是临时表,其生命周期也是当前批次的本地,但其可见性扩展到整个会话。

答案 3 :(得分:-1)

WITH n(id, name) AS 
   (SELECT id, name 
    FROM ABC
    WHERE parent = 44
        UNION ALL
    SELECT m.id, m.name 
    FROM ABC as m, n
    WHERE n.id = m.parent)
SELECT * FROM n