Reputation: 152
I Have problem with this code. I have tree in my data base and i need to select all nodes except The Node and his children, grandchilder etc. I done WITH query - it works. I can select all big family of The Node. But when i try to do SELECT ... WHERE id NOT ID (and here is the big family) i have errors...
CODE:
Select * from TALBE
where id NOT IN
(
WITH TempTable
AS
(
SELECT ...
UNION ALL
SELECT ...
)
Select id from TempTable;
);
or another version
Select * from TALBE
where id NOT IN
(
select id from
(
WITH TempTable
AS
(
SELECT ...
UNION ALL
SELECT ...
)
Select id from TempTable
)
);
In this code I need to have first 2 lines. Its not my decision - just must to have.
Errors:
Msg 156, Level 15, State 1, Line 4
Incorrect syntax near the keyword 'WITH'.
Msg 319, Level 15, State 1, Line 4
Incorrect syntax near the keyword 'with'. If this statement is a common table expression, an xmlnamespaces clause or a change tracking context clause, the previous statement must be terminated with a semicolon.
Msg 102, Level 15, State 1, Line 14
Incorrect syntax near ')'.
Upvotes: 0
Views: 84
Reputation: 33580
Something like this. You should probably read the documentation about CTEs so you understand what they are and how they are used.
Select * from TALBE
where id NOT IN
(
SELECT ID from someTable
UNION ALL
SELECT ID from SomeOtherTable
);
Now that it sounds like you want this as a recursive cte you will need to adjust this a little bit.
WITH TempTable
AS
(
SELECT ...
UNION ALL
SELECT ...
)
Select * from TALBE
where id NOT IN
(
SELECT ID from TempTable
);
Upvotes: 0
Reputation: 785
The way this code is written, the CTE query will be run for every row you're testing since a CTE is not really a result set, but a statement. This is very likely to cause performance issues down the road. A better way would be to cache the results of your query in a table in memory and use them when doing your actual select, like so:
DECLARE @badIds TABLE
(
Id INT NOT NULL --replace the INT with whatever type your Id column is
)
INSERT INTO @badIds
SELECT someId
FROM someTable
UNION ALL
SELECT someOtherId
FROM someOtherTable
...
SELECT * FROM Table WHERE id NOT IN (SELECT Id FROM @badIds)
Upvotes: 0
Reputation: 2544
As the comments have suggested, you need to remove the CTE or move it to the beginning of you're query.
http://technet.microsoft.com/en-us/library/ms190766(v=sql.105).aspx
WITH TempTable
AS
(
SELECT ...
UNION ALL
SELECT ...
)
Select * from TALBE
where id NOT IN
(
select id from TempTable
);
Upvotes: 4