I have the following SQL code for a SSRS report. I simplified the code because the original query is much longer. There is a parameter @ARTICLE which a user can input. What I want to do is create a conditional WHERE statement. If a user enters an article number (@ARTICLE) the query should filter ID's from Table1 that match with ID's for which the entered article number (@ARTICLE) have a match with a 'detailcode' from another table. If there is no article number given, do not filter (or skip the whole WHERE statement)
With the code below I get the following error:
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.'
Logically it works perfectly fine without the CASE statement, so when only the subquery is used to check for matching ID's. However, I only want to return matching IDs if the @ARTICLE parameter has a value. If it is NULL or an empty string I want to return all IDs (or just skip the entire WHERE statement). How can I include a condition in the WHERE clause that allows multiple rows to return given the example below?
I feel like my approach is way to complicated, any help is much appreciated!
DECLARE @ARTICLE AS VARCHAR(50) = '1234567'
SELECT * FROM Table1
WHERE
Table1.ID IN (
CASE
WHEN ISNULL(@ARTICLE,'')<>'' THEN
(
SELECT ID
FROM Table2
WHERE detailcode IN (@ARTICLE)
)
ELSE Table1.ID
END
)
CodePudding user response:
You're right, you're overcomplicating it a bit - if you look at the LIKE operator you can do something like:
DECLARE @filter NVARCHAR(50) = '123456';
DECLARE @f NVARCHAR(100) = '%' @filter '%';
SELECT *
FROM [Table1] AS [t1]
INNER JOIN [Table2] AS [t2]
ON [t2].[joinField] = [t1].[joinField]
AND [t2].[detailCode] LIKE @f;
Where @filter is a parameter to the stored procedure.
Or to account for detailCode being null:
DECLARE @filter NVARCHAR(50) = '123456';
DECLARE @f NVARCHAR(100) = '%' @filter '%';
IF @filter != NULL
SELECT *
FROM [Table1] AS [t1]
INNER JOIN [Table2] AS [t2]
ON [t2].[joinField] = [t1].[joinField]
AND [t2].[detailCode] LIKE @f;
ELSE
SELECT *
FROM [Table1] AS [t1]
INNER JOIN [Table2] AS [t2]
ON [t2].[joinField] = [t1].[joinField];
CodePudding user response:
I would check wether @ARTICLE is NULL or if it is NOT NULL and your subquery is fulfilled, like so:
WHERE
ISNULL(@ARTICLE, '') = ''
OR
(
ISNULL(@ARTICLE, '') <> ''
AND ID IN
(
SELECT ID FROM Table2
WHERE detailcode = @ARTICLE
)
)
CodePudding user response:
Maybe you can do it entire different, with an exists for example.
So you return all rows when @ARTICLE is null or '' OR exists at least one row in table2 with this article
The OR will have the effect that no filtering is done when the variable is null or ''
DECLARE @ARTICLE AS VARCHAR(50) = '1234567'
select t1.*
from table1 t1
where ( isnull(@ARTICLE, '') = ''
or
exists ( select 1 from table2 t2 where t2.detailcode = @ARTICLE )
)
