基于变量的条件连接或过滤器
Conditional Join or Filter based on Variable
我有一个存储过程,我正在将 22 个字符串变量从 SSRS 传递给它。变量可以是 null 也可以是字符串。当 Null 值传递给存储过程时,我需要 return 所有记录。如果传递了一个字符串,我只需要过滤那些值。在我的示例中,我使用 string_split 并将变量保存到临时 table.
Drop table if exists #Authors
Drop table if exists #Temp
CREATE TABLE #Authors
(
Id INT PRIMARY KEY,
Names VARCHAR (50) NOT NULL,
)
INSERT INTO #Authors
VALUES (1, 'AuthorA'),
(2, 'AuthorB'),
(3, 'AuthorC'),
(10, 'AuthorD'),
(12, 'AuthorE')
DECLARE
@vartest1 AS VARCHAR(20)
SET @vartest1 = 'AuthorA,AuthorB'
SELECT VALUE AS Names INTO #Temp FROM string_split(@vartest1, ',')
SELECT * FROM #Temp
SELECT * FROM #Authors a
INNER JOIN #TEMP t
ON a.Names=t.Names
SELECT *
FROM #Authors a
INNER JOIN
CASE
WHEN len(@vartest1)>0 #Temp t
ELSE #Authors a
END
ON
CASE
WHEN len(@vartest1)>0 Then #Temp.Names
Else a.Names
END = a.Names
然后我尝试创建一个案例连接,它可以连接到临时 table 或自身连接到 return 全部。我读过人们在哪里使用联合,但我认为这不适用于 22 个参数。
您是否考虑过 left join
使用检查变量是否为 null 的条件?
类似
SELECT a.* FROM #Authors a
LEFT JOIN #TEMP t
ON a.Names=t.Names
WHERE
@vartest1 is null -- Include all if input is null...
or t.names is not null -- ... Otherwise exclude where no match in #TEMP (treat like inner join)
我认为这符合您的要求。 left join
确保我们拥有 #Authors
中的所有记录,然后 WHERE
处理两种可能的情况(@vartest1 is null
获取所有记录或 t.names is not null
检查是否实际上有一场比赛)。
您可能已经意识到这一点,但没有必要使用临时 table 来处理您的拆分值。你可以这样做:
SELECT a.* FROM #Authors a
LEFT JOIN string_split(@vartest1, ',') t
ON a.Names=t.value
WHERE @vartest1 is null or t.value is not null
我觉得上面说的很合理,但更符合你原来的想法的是使用IF
like:
IF @vartest1 is null
SELECT a.* FROM #Authors a;
ELSE
SELECT a.* FROM #Authors a inner join #Temp t ON a.Names=t.Names;
我有一个存储过程,我正在将 22 个字符串变量从 SSRS 传递给它。变量可以是 null 也可以是字符串。当 Null 值传递给存储过程时,我需要 return 所有记录。如果传递了一个字符串,我只需要过滤那些值。在我的示例中,我使用 string_split 并将变量保存到临时 table.
Drop table if exists #Authors
Drop table if exists #Temp
CREATE TABLE #Authors
(
Id INT PRIMARY KEY,
Names VARCHAR (50) NOT NULL,
)
INSERT INTO #Authors
VALUES (1, 'AuthorA'),
(2, 'AuthorB'),
(3, 'AuthorC'),
(10, 'AuthorD'),
(12, 'AuthorE')
DECLARE
@vartest1 AS VARCHAR(20)
SET @vartest1 = 'AuthorA,AuthorB'
SELECT VALUE AS Names INTO #Temp FROM string_split(@vartest1, ',')
SELECT * FROM #Temp
SELECT * FROM #Authors a
INNER JOIN #TEMP t
ON a.Names=t.Names
SELECT *
FROM #Authors a
INNER JOIN
CASE
WHEN len(@vartest1)>0 #Temp t
ELSE #Authors a
END
ON
CASE
WHEN len(@vartest1)>0 Then #Temp.Names
Else a.Names
END = a.Names
然后我尝试创建一个案例连接,它可以连接到临时 table 或自身连接到 return 全部。我读过人们在哪里使用联合,但我认为这不适用于 22 个参数。
您是否考虑过 left join
使用检查变量是否为 null 的条件?
类似
SELECT a.* FROM #Authors a
LEFT JOIN #TEMP t
ON a.Names=t.Names
WHERE
@vartest1 is null -- Include all if input is null...
or t.names is not null -- ... Otherwise exclude where no match in #TEMP (treat like inner join)
我认为这符合您的要求。 left join
确保我们拥有 #Authors
中的所有记录,然后 WHERE
处理两种可能的情况(@vartest1 is null
获取所有记录或 t.names is not null
检查是否实际上有一场比赛)。
您可能已经意识到这一点,但没有必要使用临时 table 来处理您的拆分值。你可以这样做:
SELECT a.* FROM #Authors a
LEFT JOIN string_split(@vartest1, ',') t
ON a.Names=t.value
WHERE @vartest1 is null or t.value is not null
我觉得上面说的很合理,但更符合你原来的想法的是使用IF
like:
IF @vartest1 is null
SELECT a.* FROM #Authors a;
ELSE
SELECT a.* FROM #Authors a inner join #Temp t ON a.Names=t.Names;