Reputation: 1178
I'm wishing I could do something like the following in SQl Server 2005 (which I know isnt valid) for my where clause. Sometimes @teamID (passed into a stored procedure) will be the value of an existing teamID, otherwise it will always be zero and I want all rows from the Team table.
I researched using Case and the operator needs to come before or after the entire statement which prevents me from having a different operator based on the value of @teamid. Any suggestions other than duplicating my select statements.
declare @teamid int
set @teamid = 0
Select Team.teamID From Team
case @teamid
when 0 then
WHERE Team.teamID > 0
else
WHERE Team.teamID = @teamid
end
Upvotes: 9
Views: 24772
Reputation: 35171
Even simpler than Andomar's answer, and assuming that id is never 0 (as for most auto-increment ids) is
SELECT Team.teamID
FROM Team
WHERE @teamid = 0 or Team.teamID = @teamid;
That predicate is always true when @teamid is zero, and otherwise only true when it matches a particular row's teamId.
Note however: this works pretty efficiently on Sybase 11 or above; it worked pretty inefficiently on MS SQL server 2003; I don't know how it works on the current version of MS SQL Server.
Also, you can use case; you just have to put the case in where clause, not the where clause in the case. So your original query would be:
Select Team.teamID
From Team
where
case when @teamid = 0 then 0 else Team.teamID end = @teamId;
Note that this is likely to be less efficient, however, as it must be evaluated per row and will also likely result in a full table scan.
The form I gave above is more likely to be rewritten by a smart query optimizer (your mileage depends on your RDBMS) to use an index when @teamid is not zero.
Upvotes: 2
Reputation: 8043
If you could treat Null as all records:
WHERE Team.teamID = ISNULL(@teamid, Team.teamID)
Upvotes: 0
Reputation: 332661
Without using dynamic SQL, the most performant option is:
IF @teamid = 0
BEGIN
SELECT t.teamid
FROM TEAM t
WHERE t.teamid > 0
END
ELSE
BEGIN
SELECT t.teamid
FROM TEAM t
WHERE t.teamid = @teamid
END
Using Dynamic SQL:
DECLARE @SQL NVARCHAR(4000)
SET @SQL = 'SELECT t.teamid
FROM TEAM t
WHERE 1 = 1 '
SET @SQL = @SQL + CASE @teamid
WHEN 0 THEN ' AND t.teamid > 0 '
ELSE ' AND t.teamid = @teamid '
END
BEGIN
EXEC sp_EXECUTESQL @SQL N'@teamid INT', @teamid
END
Beware that sp_EXECUTESQL
caches the query plan, while EXEC will not. Read this: http://www.sommarskog.se/dynamic_sql.html
Upvotes: 5
Reputation: 7412
What about:
Select Team.teamID From Team Where (@teamid=0 and team.teamID>0) or (@teamid<>0 and team.teamid=@teamid)
Upvotes: 2
Reputation: 238186
You can do that without a case:
SELECT Team.teamID
FROM Team
WHERE (@teamid = 0 AND Team.teamID > 0)
OR (@teamid <> 0 AND Team.teamID = @teamid)
Upvotes: 22