在SQL中是否可以在WITH内使用WITH

时间:2014-06-12 01:47:00

标签: sql view

在SQL中,是否可以将WITH放在WITH?

以下面的查询为例,

WITH Temp ([Description], [Amount], [OverdueBy])
AS 
(select Description, SUM(Amount) as Amount, (DATEDIFF(day,DueDate,GETDATE())) as OverdueBy  from brvAPAllInvoices 
Where PaidDate is null and APCo = 1 and Amount > 0 
Group By Description, DueDate, APRef

)

select * from Temp

我想创建一个"虚拟"基于上述查询的临时表。是否可以使用另一个WITH来包含它?

有些事情如下:

WITH Temp2 ([Description], [Amount], [OverdueBy])
AS
(
WITH Temp ([Description], [Amount], [OverdueBy])
AS 
(select Description, SUM(Amount) as Amount, (DATEDIFF(day,DueDate,GETDATE())) as OverdueBy  from brvAPAllInvoices 
Where PaidDate is null and APCo = 1 and Amount > 0 
Group By Description, DueDate, APRef

)

select * from Temp)

select * from Temp2

3 个答案:

答案 0 :(得分:2)

不,您无法在CTE中定义CTE,但您可以在一个声明中定义多个CTE并引用其他CTE。

; with a as (
    select * from some_table
),
b as (
   select * 
   from another_table t
     inner join a ON (t.key = a.key)
)
select * 
from b

答案 1 :(得分:2)

根据您的dbms,您可以拥有多个WITH语句,嵌套与否。 (用PostgreSQL说明。)SQL Server doesn't allow nesting common table expressions。 (搜索 CTE_query_definition 。)

<强>嵌套

with today as (
  with yesterday as (select current_date - interval '1' day as yesterday)
  select yesterday + interval '1' day as today from yesterday 
)
select cast(today as date) from today
today
--
2014-06-11

当您嵌套公用表表达式时,嵌套的CTE在其封闭的CTE之外是不可见的。

with today as (
  with yesterday as (select current_date - interval '1' day as yesterday)
  select yesterday + interval '1' day as today from yesterday 
)
select * from yesterday
ERROR: relation "yesterday" does not exist

<强>嵌套的

with yesterday as (
  select current_date - interval '1' day as yesterday
), 
today as (
  select yesterday + interval '1' day as today from yesterday 
)
select cast(yesterday as date) as dates from yesterday
union all
select cast(today as date) from today
dates
--
2014-06-10
2014-06-11

当您使用连续的,未经证实的CTE时,较早的CTE对后者可见,但反之亦然。

with today as (
  select yesterday + interval '1' day as today from yesterday 
),
yesterday as (
  select current_date - interval '1' day as yesterday
) 
select yesterday from yesterday
union all
select today from today
ERROR:  relation "yesterday" does not exist

答案 2 :(得分:0)

您通常会执行以下操作;

WITH Temp ([Description], [Amount], [OverdueBy])
AS 
(select Description, SUM(Amount) as Amount, (DATEDIFF(day,DueDate,GETDATE())) as OverdueBy  from brvAPAllInvoices 
Where PaidDate is null and APCo = 1 and Amount > 0 
Group By Description, DueDate, APRef
), Temp2 ([Description], [Amount], [OverdueBy]) AS 
(
    SELECT * FROM Temp
)
select * from Temp2

在你做作的例子中,显然没有多大用处,因为两个表结构几乎相同。我倾向于将CTE视为命名派生表而不是临时表....即使它们不仅仅是派生表