开发者

How to nest CTE properly

This question was asked few other times, but I still did not manage to sort out the right answer or proper way to do this:

...

;WITH CTE AS
(
  SELECT * FROM ...
)
SELECT *, [dbo].[udf_BetaInv](A, B, C, D) AS 'Loss'
FROM CTE
WHERE (Loss >= @MinRetention)

This does not work and I cannot create the stored procedure, clearly I cannot use Loss in the WHERE because does not exist in that scope.

I would like to use another CTE to wrap this one so I can put the WHERE on the outer one but not does not seem to work, tried this:

;WITH CTE AS
(
  SELECT * FROM ...
)
SELECT *, [dbo].[udf_BetaInv(A, B, C, D) AS 'Loss'
FROM CTE,
RESULTS AS
(SELECT * FROM CTE)
  SELECT *
  FROM RESULTS
  WHERE (Loss >= @MinRetention)

But it does not compile in SQL Server, I get an error that a '(' is misplaces many rows above but has nothing to do, if I remove the second CTE it works fine.

I only want 开发者_JAVA技巧to avoid code duplication, not want to call my [udf_BetaInv] twice in the select and also in the where.


You have an intermediate SELECT that you should not have. This should work:

;WITH CTE AS
(
  SELECT * FROM ...
),
RESULTS AS
(
  SELECT *, [dbo].[udf_BetaInv(A, B, C, D) AS 'Loss'
  FROM CTE
)
SELECT *
FROM RESULTS
WHERE (Loss >= @MinRetention)


Obviously the problem with the first query is that 'Loss' is just a column alias and can't be used in a WHERE clause. You're right that using it in a CTE would avoid duplicating the expression. Here's how you'd do that;

WITH CTE AS 
( 
    SELECT * FROM ... 
),
CteWithLoss AS ( 
    SELECT *, [dbo].[udf_BetaInv](A, B, C, D) AS 'Loss' 
    FROM CTE
)
SELECT *
FROM CteWithLoss 
WHERE (Loss >= @MinRetention);

On a side note: See if you can break the habit of starting your CTE definitions with ;WITH and instead get into the habit of ending all your SQL statements with a semi-colon. It's more readable and better practice.


Below is the example of nested CTE.

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

select * from cte_data1
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜