2016-07-17 188 views
1

添加/跳過哪裏條款我有下面的查詢,它從表變量中獲取TagId列表並返回列表。基於條件

但我需要添加該CategoryId WHERE條件只有@Tags有記錄。

只有當我的表變量有記錄才能添加WHERE條件,否則運行1 = 1(總是爲true)的相同查詢並跳過類別過濾器?

DECLARE @TagIdList NVARCHAR(100) = '22,25,47' 
DECLARE @Tags TABLE (TagId INT); 

WITH CSVtoTable 
AS (
    SELECT CAST('<XMLRoot><RowData>' + REPLACE(t.val, ',', '</RowData><RowData>') + '</RowData></XMLRoot>' AS XML) AS x 
    FROM (
     SELECT @TagIdList 
     ) AS t(val) 
    ) 
INSERT INTO @Tags (TagId) 
SELECT m.n.value('.[1]', 'varchar(8000)') AS TagId 
FROM CSVtoTable 
CROSS APPLY x.nodes('/XMLRoot/RowData') m(n) 

SELECT BookingId 
    ,C.CategoryName 
FROM Booking B 
INNER JOIN Category C ON C.CategoryId = B.CategoryId 
WHERE (
     b.IsDeleted = 0 
     OR b.IsDeleted IS NULL 
     ) 
-- Add the below where condition only if @Tags has records, else use 1=1 
    AND C.CategoryId IN (
     SELECT DISTINCT CategoryId 
     FROM CategoryXTag con 
     WHERE TagId IN (
       SELECT TagId 
       FROM @Tags 
       ) 
     ) 

回答

1

最終你只需要改變查詢結束。如果性能是一個問題,您可能需要考慮在這兩種情況下使用if塊的兩個分支,即使技術上可能將邏輯擠壓到通常不會優化的單個查詢中。

AND 
(
    C.CategoryId IN (
     SELECT CategoryId 
     FROM CategotryXTag 
     WHERE TagId IN (
      SELECT TagId 
      FROM @Tags 
     ) 
    ) 
    OR 
    (SELECT COUNT(*) FROM @Tags) = 0 
) 
+0

這看起來很簡單,很有效 – Developer

1
declare int @tagcount = (select count(*) from @Tags); 

SELECT BookingId, C.CategoryName 
FROM Booking B 
INNER JOIN Category C 
     ON C.CategoryId = B.CategoryId 
     AND isnull(b.IsDeleted, 0) = 0 
INNER JOIN CategoryXTag con 
     ON C.CategoryId = con.CategoryId 
INNER JOIN @Tags tags 
     ON tags.TagID = con.TagID 
     OR @tagcount = 0; 

如果@tags是空的,你可能需要把一個記錄它與永遠不會被使用的值,然後或價值

if(@tagcount = 0) insert into @tags values (-100); 
or tags.TagID = -100; 
+0

當我不通過標籤列表時,我需要拉動沒有在CategoryXTag中輸入的記錄。但查詢內部加入該表 – Developer

+0

好的,你可以指出另一個答案。你應該給它一張支票。 – Paparazzi

1

您無需修改​​您的where子句。相反,你運行你的最終查詢之前填充@TagsTagIdCategoryXTag達到同樣的邏輯,如果@Tags是空的初始插件後:

if ((select count(*) from @Tags) = 0) 
    insert into @Tags 
    select distinct TagId 
    from CategoryXTag; 
0

我聲明一個變量爲@tags表:

declare @needTagsFilter bit 
set @needTagsFilter = case when exists(select 1 from @Tags) then 1 else 0 end 

和改變where子句等

AND (
    (@needTagsFilter = 0) OR 
    (C.CategoryId IN (
     SELECT DISTINCT CategoryId 
     FROM CategoryXTag con 
     WHERE TagId IN (
      SELECT TagId 
      FROM @Tags 
      ) 
    ) 
    ) 

COUNT(*)是慢然後存在。將count /直接添加到原始查詢的缺點是SQL Server可能會爲所有行執行它。