簡體   English   中英

如何有選擇地基於變量應用WHERE IN子句?

[英]How to optionally apply a WHERE IN clause based on a variable?

我有一個存儲過程,需要按以逗號分隔的列表(即'1,2,3' )傳遞的ID列表進行篩選。

我想應用一個WHERE IN子句,該子句將與這些id匹配,但僅在變量包含任何內容( IS NOT NULL AND <> ''IS NOT NULL AND <> ''

這是問題的簡化提琴: http : //sqlfiddle.com/#!18/5f6be/1

目前,它適用於單個和多個ID。 但是,當傳遞''NULL它應該返回所有內容,但不返回任何內容。

出現CTE和分頁的內容是有原因的,請提供一個不會改變它的解決方案。

使用DelimitedSplit8k_lead您可以通過執行以下操作來達到此目的:

CREATE PROC YourProc @List varchar(8000) = NULL AS
BEGIN

    SELECT {YourColumns}
    FROM YourTable YT
         OUTER APPLY dbo.DelimitedSplit8k_Lead(@List,',') DS
    WHERE DS.item = YT.YourColumn
       OR NULLIF(@List,'') IS NULL
    OPTION (RECOMPILE);
END

使用OUTER APPLY ,就像傳遞NULL ,數據集也不會消除。 RECOMPILE在那里,因為它變成了“全部捕獲查詢”,並增加了對NULL的處理。

為什么不在WHERE子句中使用JOIN而不是子查詢。

set @userIds = nullif(ltrim(@userIds),'')
select u.*
from Users u
left join string_split(@userIds,',') s on u.Id=s.value
where s.value is not null or @userIds is null

老派的方法:

WHERE
(@userIds IS NULL OR @userIds = '' OR U.Id IN (SELECT * FROM STRING_SPLIT(@userIds, ',')))

最后添加OPTION (RECOMPILE) ,以便工作和調整計划。


編輯:基於注釋,此注釋將生成兩個表掃描。 它對我的LocalDb設置沒有任何影響,但是無論如何都不要依賴它。

WHERE U.Id IN
(
   SELECT * FROM STRING_SPLIT(@userIds, ',')
   UNION ALL
   SELECT U.Id WHERE NULLIF(@userIds, '') IS NULL
)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM