I have a basic SQL query, starting with:
SELECT top 20 application_id, [name], location_id FROM apps
Now, I would like to finish it so that it
You are asking different questions here. This is the answer to your original question (about the ternary operator, but as you can see, you don't need anything like a ternary operator for this):
SELECT top 20 application_id, [name], location_id
FROM apps
WHERE @lid = 0 OR location_id IN (@lid)
But that was before we knew that @lid was a varchar and could contain different comma separated values.
Well, this (about the csv) is another question which has been asked here before:
Passing an "in" list via stored procedure
T-SQL stored procedure that accepts multiple Id values
See this entry in my blog:
If your @lid
is a comma-delimited list of integers, use this:
WITH cd AS
(
SELECT 1 AS first, CHARINDEX(',', @lid, 1) AS next
UNION ALL
SELECT next + 1, CHARINDEX(',', @lid, next + 1)
FROM cd
WHERE next > 0
),
lid AS
(
SELECT CAST(SUBSTRING(@lid, first, CASE next WHEN 0 THEN LEN(@lid) + 1 ELSE next END - first)AS INT) AS id
FROM cd
)
SELECT d.*
FROM (
SELECT DISTINCT id
FROM lid
) l
JOIN apps a
ON a.location_id = l.id
AND @lid <> '0'
UNION ALL
SELECT *
FROM apps a
WHERE @lid = '0'
This is much more efficient than using OR
constructs.
Try using Case, which serves the purpose of an IIF or a ternary operator. Please check this link http://msdn.microsoft.com/en-us/library/ms181765.aspx
cheers
While it is not exactly a best practice to use 1=1, it does the trick here.
SELECT top 20 application_id, [name], location_id FROM apps
WHERE
(@lid > 0 and @lid = location_id)
or
(isnull(@lid, 0) <= 0 and 1=1)
One way is to split the string on the commas, strip out the spaces and insert the values into a temporary table. Then you can join your query against the temp table.
This is a T-SQL code snippet that splits a comma-separated list and inserts the members into a temporary table. Once you've populated the table you can join against it.
-- This bit splits up a comma separated list of key columns
-- and inserts them in order into a table.
--
if object_id ('tempdb..#KeyCols') is not null
drop table #KeyCols
create table #KeyCols (
,KeyCol nvarchar (100)
)
set @comma_pos = 0
set @len = len(@KeyCols)
while @len > 0 begin
set @comma_pos = charindex(',', @KeyCols)
if @comma_pos = 0 begin
set @KeyCol = @KeyCols
set @KeyCols = ''
end else begin
set @KeyCol = left (@KeyCols, @comma_pos - 1)
set @KeyCols = substring(@KeyCols,
@comma_pos + 1,
len (@KeyCols) - @comma_pos)
end
insert #KeyCols (KeyCol)
values (@KeyCol)
set @len = len (@KeyCols)
end
Assuming @locid & @lid are the same, I'm going to use @locid... The following would work. I've split it up to keep it looking good on SO.
SELECT application_id, [name], location_id
FROM apps
WHERE
(
@locid = 0
OR
CHARINDEX
(
',' + CAST(location_id AS VARCHAR(50)) + ','
,
',' + @locid + ','
,
0
) > 0
)