1

我想从数据库中选择结果,该数据库根据使用IN关键字是否存在于参数中来选择记录:

SELECT * FROM report_view
WHERE project_id = 1
AND versionName IN (SELECT LTRIM(string) COLLATE DATABASE_DEFAULT FROM [dbo].[func_ParseString](@milestoneInput))

这很好用,但COALESCE如果 IN 语句中没有返回任何内容,我想使用关键字来恢复所有内容。

有没有办法做到这一点?

4

2 回答 2

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使用 a而不是以下内容可能会更好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 是仅仅相当于语法糖还是实际上强制函数只被评估一次;其他人可以对此进行调查并提供正确的答案:)

于 2013-07-12T10:48:52.750 回答
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 的子句。

于 2013-07-12T11:51:19.453 回答