2013-07-12 23 views
1

我要選擇,取決於他們是否使用IN關鍵字參數存在於選擇記錄的數據庫的結果:使用在同一個SQL語句COALESCE和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語句中沒有返回任何內容。

有沒有辦法做到這一點?

回答

0

使用COALESCE將中的NULL替換爲具有給定值的中的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) 
     ) 
    ) 
) 

我不知道這會打電話給你的功能,但有多少次。你可能會喜歡的東西以下更好,使用ORUNION ALL代替:

;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根本達句法糖或實際強制功能將只計算雖然一次;別人可以調查此問題並提供適當的答案:)

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時,無論是值匹配或有列表中沒有匹配。

相關問題