提问人:Joe Phillips 提问时间:9/12/2009 最后编辑:spenderJoe Phillips 更新时间:6/17/2020 访问量:163549
您可以为公共表表达式创建嵌套的 WITH 子句吗?
Can you create nested WITH clauses for Common Table Expressions?
问:
WITH y AS (
WITH x AS (
SELECT * FROM MyTable
)
SELECT * FROM x
)
SELECT * FROM y
这样的事情有效吗?我之前尝试过,但我无法让它工作。
答:
382赞
spender
9/12/2009
#1
虽然不是严格嵌套的,但您可以使用通用表表达式在后续查询中重用以前的查询。
为此,您要查找的语句形式将是
WITH x AS
(
SELECT * FROM MyTable
),
y AS
(
SELECT * FROM x
)
SELECT * FROM y
评论
2赞
Jason TEPOORTEN
7/29/2013
谢谢。我能够在 Oracle 中做到这一点:使用 J 作为(从 DUAL 中选择 1 作为 1),Q 作为(从 J 中选择 J.*,2 作为 2)从 Q 中选择 *
6赞
symbiont
12/30/2016
这不是嵌套的
21赞
peterh
5/30/2017
从本质上讲,帖子的意思是,你不能这样做,但这不是一个大问题。
2赞
Joe Phillips
6/3/2017
是的,这是一个可以接受的答案,因为我试图通过嵌套实现的目标与它最终给我的东西是一样的
4赞
Christiaan Westerbeek
9/11/2018
仅仅因为查询 2 不在查询 1 的括号内,就说明这不是嵌套的,这听起来像是一个弱参数。我认为它是嵌套的(不是递归嵌套的),因为查询 2 使用查询 1 的结果,这也发生在嵌套中。是否定义嵌套只能在子项位于其父括号(或类似)符号内时?
17赞
David Andres
9/12/2009
#2
您可以执行以下操作,这称为递归查询:
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
评论
0赞
Teamothy
11/16/2021
很棒的建议,将主要 SELECT 放入下一个 WITH 子句,然后从最后一个 WITH 查询中 SELECT。谢谢你:)
9赞
Adriaan Stander
9/12/2009
#3
With 不能嵌入,但它确实可以连续工作
;WITH A AS(
...
),
B AS(
...
)
SELECT *
FROM A
UNION ALL
SELECT *
FROM B
编辑修复了语法...
另外,请看以下示例
SQLFiddle 演示
-1赞
Don Rolling
3/25/2016
#4
这些答案非常好,但就正确订购物品而言,您最好看看这篇文章 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
评论
1赞
Joe Phillips
3/25/2016
我最初的问题从未说过将数据合并在一起。它本来可以很容易地连接数据
0赞
Subhransu Panda
12/21/2016
#5
我们可以创建嵌套的 CTE.请看下面的 CTE 示例
;with cte_data as
(
Select * from [HumanResources].[Department]
),cte_data1 as
(
Select * from [HumanResources].[Department]
)
select * from cte_data,cte_data1
评论
5赞
Joe Phillips
12/21/2016
你来晚了一点;)
6赞
Meower68
8/2/2018
这是连续的 CTE,而不是嵌套的 CTE
0赞
natur3
10/25/2017
#6
我试图测量事件之间的时间,除了一个在开始和结束之间有多个进程的条目。在其他单行流程的上下文中,我需要它。
我使用带有内部连接的 select 作为第 N 个 cte 中的 select 语句。第二个 cte 我需要提取 X 上的开始日期和 Y 上的结束日期,并使用 1 作为 id 值来左连接以将它们放在一行上。
对我有用,希望这会有所帮助。
cte_extract
as
(
select ps.Process as ProcessEvent
, ps.ProcessStartDate
, ps.ProcessEndDate
-- select strt.*
from dbo.tbl_some_table ps
inner join (select max(ProcessStatusId) ProcessStatusId
from dbo.tbl_some_table
where Process = 'some_extract_tbl'
and convert(varchar(10), ProcessStartDate, 112) < '29991231'
) strt on strt.ProcessStatusId = ps.ProcessStatusID
),
cte_rls
as
(
select 'Sample' as ProcessEvent,
x.ProcessStartDate, y.ProcessEndDate from (
select 1 as Id, ps.Process as ProcessEvent
, ps.ProcessStartDate
, ps.ProcessEndDate
-- select strt.*
from dbo.tbl_some_table ps
inner join (select max(ProcessStatusId) ProcessStatusId
from dbo.tbl_some_table
where Process = 'XX Prcss'
and convert(varchar(10), ProcessStartDate, 112) < '29991231'
) strt on strt.ProcessStatusId = ps.ProcessStatusID
) x
left join (
select 1 as Id, ps.Process as ProcessEvent
, ps.ProcessStartDate
, ps.ProcessEndDate
-- select strt.*
from dbo.tbl_some_table ps
inner join (select max(ProcessStatusId) ProcessStatusId
from dbo.tbl_some_table
where Process = 'YY Prcss Cmpltd'
and convert(varchar(10), ProcessEndDate, 112) < '29991231'
) enddt on enddt.ProcessStatusId = ps.ProcessStatusID
) y on y.Id = x.Id
),
....其他 CTE
0赞
KOBER
6/16/2020
#7
不支持嵌套的 '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
评论