您可以为公用表表达式创建嵌套的WITH子句吗?

时间:2009-09-11 22:07:36

标签: sql sql-server tsql nested common-table-expression

WITH y AS (
    WITH x AS (
        SELECT * FROM MyTable
    )
    SELECT * FROM x
)
SELECT * FROM y

这样的事情有用吗?我之前尝试过,但我无法让它发挥作用。

7 个答案:

答案 0 :(得分:262)

虽然没有严格嵌套,但您可以使用公用表表达式重用以后的查询。

为此,您要查找的语句形式为

WITH x AS 
(
    SELECT * FROM MyTable
), 
y AS 
(
    SELECT * FROM x
)
SELECT * FROM y

答案 1 :(得分:9)

您可以执行以下操作,称为递归查询:

WITH y
AS
(
  SELECT x, y, z
  FROM MyTable
  WHERE [base_condition]

  UNION ALL

  SELECT x, y, z
  FROM MyTable M
  INNER JOIN y ON M.[some_other_condition] = y.[some_other_condition]
)
SELECT *
FROM y

您可能不需要此功能。为了更好地组织我的查询,我已经完成了以下操作:

WITH y 
AS
(
  SELECT * 
  FROM MyTable
  WHERE [base_condition]
),
x
AS
(
  SELECT * 
  FROM y
  WHERE [something_else]
)
SELECT * 
FROM x

答案 2 :(得分:6)

使用嵌入不起作用,但它确实连续工作

;WITH A AS(
...
),
B AS(
...
)
SELECT *
FROM A
UNION ALL
SELECT *
FROM B

修改 修正了语法......

另外,请看下面的例子

SQLFiddle DEMO

答案 3 :(得分:0)

这些答案非常好,但就正确订购物品而言,你最好还是看看这篇文章 http://dataeducation.com/dr-output-or-how-i-learned-to-stop-worrying-and-love-the-merge

以下是他的查询示例。

WITH paths AS ( 
    SELECT 
        EmployeeID, 
        CONVERT(VARCHAR(900), CONCAT('.', EmployeeID, '.')) AS FullPath 
    FROM EmployeeHierarchyWide 
    WHERE ManagerID IS NULL

    UNION ALL

    SELECT 
        ehw.EmployeeID, 
        CONVERT(VARCHAR(900), CONCAT(p.FullPath, ehw.EmployeeID, '.')) AS FullPath 
    FROM paths AS p 
        JOIN EmployeeHierarchyWide AS ehw ON ehw.ManagerID = p.EmployeeID 
) 
SELECT * FROM paths order by FullPath

答案 4 :(得分:0)

我们可以创建嵌套的cte.please,参见下面的cte示例

;with cte_data as 
(
Select * from [HumanResources].[Department]
),cte_data1 as
(
Select * from [HumanResources].[Department]
)

select * from cte_data,cte_data1

答案 5 :(得分:0)

我试图测量事件之间的时间,除了在开始和结束之间有多个进程的条目之外。我需要在其他单行流程中使用它。

我在第N个cte中使用了带内连接的select作为我的select语句。第二个cte我需要在Y上提取开始日期并在Y上结束日期,并使用1作为id值来左连接以将它们放在一行上。

适合我,希望这会有所帮助。

false

....其他ctes

答案 6 :(得分:0)

不支持嵌套的“ With”,但是您始终可以将第二个With用作子查询,例如:

WITH A AS (
                --WITH B AS ( SELECT COUNT(1) AS _CT FROM C ) SELECT CASE _CT WHEN 1 THEN 1 ELSE 0 END FROM B --doesn't work
                SELECT CASE WHEN count = 1 THEN 1 ELSE 0 END AS CT FROM (SELECT COUNT(1) AS count FROM dual)
                union all
                select 100 AS CT from dual
           )
              select CT FROM A