Monday
Oct272008
Cannot use CTE with Exists Clause
Monday, October 27, 2008 at 1:24PM
Apparently the syntax for the CTE does not work inside an EXISTS function. The solution, however, is very simple; Just use a derived table instead. {Oh yeah forgot that before CTEs we use to use derived tables instead.}
-- Sorry this code doesn't work due to CTE in EXISTS Function IF EXISTS( WITH LargeDepartmentNewHires AS ( SELECT HREDH.DepartmentID FROM HumanResources.EmployeeDepartmentHistory HREDH WHERE HREDH.StartDate BETWEEN '1/1/1999' AND '12/31/1999' GROUP BY HREDH.DepartmentID , YEAR(HREDH.StartDate) HAVING COUNT(*) >=10 ) SELECT HRE.* FROM HumanResources.Employee HRE INNER JOIN HumanResources.EmployeeDepartmentHistory HREDH ON HRE.EmployeeID = HREDH.EmployeeID INNER JOIN LargeDepartmentNewHires LDNH ON HREDH.DepartmentID = LDNH.DepartmentID ) BEGIN PRINT 'Yes it exists' END ELSE BEGIN PRINT 'Does NOT exists' ENDUse a derived table instead of a CTE
--This does work IF EXISTS( SELECT HRE.* FROM HumanResources.Employee HRE INNER JOIN HumanResources.EmployeeDepartmentHistory HREDH ON HRE.EmployeeID = HREDH.EmployeeID INNER JOIN ( SELECT HREDH.DepartmentID FROM HumanResources.EmployeeDepartmentHistory HREDH WHERE HREDH.StartDate BETWEEN '1/1/1999' AND '12/31/1999' GROUP BY HREDH.DepartmentID , YEAR(HREDH.StartDate) HAVING COUNT(*) >=10 ) LDNH --LargeDepartmentNewHires ON HREDH.DepartmentID = LDNH.DepartmentID ) BEGIN PRINT 'Yes it exists' END ELSE BEGIN PRINT 'Does NOT exists' ENDIf your CTE is a hierarchical query then there isn't much you can do inside the exist statement. However, remember what and how the EXISTS function works. Its purpose is to return a true as soon as the containing query returns any rows if any exist at all. To mimic this functionality rewrite the query to return a count of the rows would have been found in the EXISTS function. If the count is not 0 then it the true that the rows exist. This isn't the most efficient but it is a valid solution. Keep in mind to optimize performance return as little data as possible.
DECLARE @ReturnedRows INT ; WITH LargeDepartmentNewHires AS ( SELECT HREDH.DepartmentID FROM HumanResources.EmployeeDepartmentHistory HREDH WHERE HREDH.StartDate BETWEEN '1/1/1999' AND '12/31/1999' GROUP BY HREDH.DepartmentID , YEAR(HREDH.StartDate) HAVING COUNT(*) >=10 ) SELECT @ReturnedRows = COUNT(*) FROM HumanResources.Employee HRE INNER JOIN HumanResources.EmployeeDepartmentHistory HREDH ON HRE.EmployeeID = HREDH.EmployeeID INNER JOIN LargeDepartmentNewHires LDNH ON HREDH.DepartmentID = LDNH.DepartmentID IF @ReturnedRows != 0 BEGIN PRINT 'Yes it exists' END ELSE BEGIN PRINT 'Does NOT exists' END
Reader Comments (1)
DECLARE @foo bit;
SET @foo = 0;
WITH ShouldBeEmpty AS
(
SELECT 1 AS AnyCol
--WHERE 1 = 0
WHERE 1 = 1
)
SELECT TOP 1 @foo = 1
FROM ShouldBeEmpty
IF @foo = 1
BEGIN
SELECT 'It exists!'
END