我想从数据库中选择结果,该数据库根据使用IN
关键字在参数中是否存在来选择记录:
SELECT * FROM report_view
WHERE project_id = 1
AND versionName IN (SELECT LTRIM(string) COLLATE DATABASE_DEFAULT FROM [dbo].[func_ParseString](@milestoneInput))
这样可以正常工作,但是如果在IN语句中没有返回任何内容,我想使用COALESCE
关键字来恢复所有内容。
有办法做到这一点吗?
答案 0 :(得分:0)
使用COALESCE
将单列中的NULL替换为给定值。使用NOT EXISTS
在结果表中指定无行条件。它看起来像你想要的是:
SELECT * FROM report_view
WHERE project_id = 1
AND (
versionName IN (
SELECT LTRIM(string) COLLATE DATABASE_DEFAULT
FROM [dbo].[func_ParseString](@milestoneInput)
)
OR NOT EXISTS (
SELECT 1
FROM report_view
WHERE project_id = 1
AND versionName IN (
SELECT LTRIM(string) COLLATE DATABASE_DEFAULT
FROM [dbo].[func_ParseString](@milestoneInput)
)
)
)
我不知道这会多少次调用你的功能。使用UNION ALL
代替OR
,您可能会更好地使用以下内容:
;WITH VersionNames AS (
SELECT LTRIM(string) COLLATE DATABASE_DEFAULT AS versionName
FROM [dbo].[func_ParseString](@milestoneInput)
)
SELECT *
FROM report_view
WHERE project_id = 1
AND versionName IN (SELECT versionName from VersionNames)
UNION ALL
SELECT *
FROM report_view
WHERE project_id = 1
AND NOT EXISTS
(
SELECT 1
FROM report_view
WHERE project_id = 1
AND versionName IN (SELECT versionName from VersionNames)
)
我不确定使用CTE是否仅仅意味着语法糖或实际上强制该功能仅被评估一次;其他人可以对此进行调查并提供正确的答案:)
答案 1 :(得分:0)
这是一个将所有逻辑放在exists
子句中的替代方法。
我们的想法是使用窗口函数来查看是否存在任何匹配以及确定特定字符串是否匹配。
SELECT *
FROM report_view
WHERE project_id = 1 and
exists (select 1
from (SELECT sum(case when ltrim(ps.string) = rv.VersionName then 1 else 0
end) over () as NumMatches,
(case when ltrim(ps.string) = rv.VersionName then 1 else 0
end) as IsMatch
FROM [dbo].[func_ParseString](@milestoneInput) ps
) t
where IsMatch = 1 or NumMatchs = 0
)
密钥是where
子句,当值匹配或列表中没有匹配时,该子句返回true。