I came across a scenario where I need to filter rows based on a combination of values. Let me explain using an example:
I have 2 tables as shown here:
For easy structuring I am including the T-SQL statements:
create table employees
(
empId int,
empname varchar(100),
empSalary money
)
insert into employees
values (1, 'John', 8000), (2, 'Sam', 9800), (3, 'Ray', 9500)
create table empLocations
(
locId int,
empId int
)
insert into empLocations
values (1, 1), (2, 1), (3, 2), (4, 3), (5, 1)
I wish to get (without cross joins) the rows of employees who stays in location 1 and 4 (locIds).
In this example it should return John and Ray.
Please note there are many conditions I am checking here and the location wise filtering is optional. Hence the structure of query should be
declare @locationIds varchar(100) = '1,4'
select *
from employees
where
(0 = case when (@locationIds is null) then 0 else 1 end)
or
---<here goes the condition>----- in (select strg from [dbo].[SplitStringi] (@locationIds,',') )
)
Please note in the above example I have used a function to return values from comma separated values as below
CREATE FUNCTION [dbo].[SplitStringi]
(@str nvarchar(4000),
@separator char(1))
RETURNS TABLE
AS
RETURN (
WITH tokens(p, a, b) AS
(
SELECT
1, 1,
CHARINDEX(@separator, @str)
UNION ALL
SELECT
p + 1, b + 1,
CHARINDEX(@separator, @str, b + 1)
FROM tokens
WHERE b > 0
)
SELECT
p indx,
SUBSTRING(@str, a,
CASE WHEN b > 0 THEN b-a ELSE 4000 END) AS strg
FROM tokens
)
3条答案
按热度按时间ncgqoxb01#
Since you're using SQL Server 2019, you can use the built-in
STRING_SPLIT
function instead of a custom function to split strings.This refactored example uses
STRING_SPLIT
and simplifies the check for the optional parameter. Additionally, theOPTION(RECOMPILE)
hint will eliminate theIN
predicate from the query plan at compile time when the location list isNULL
.y3bcpkx12#
I got it
r3i60tvu3#
You can do it as follows :
Here is a working demo in SQL Server 2019
This gives you expected output as :
Here is a more simplified query :
Working demo using DBFiddle