Hinzufügen / Überspringen WHERE CLAUSE basierend auf Bedingung

Ich habe die folgende Abfrage, die eine TagId-list aus der Tabellenvariable nimmt und die list zurückgibt.

Aber ich muss diese KategorieId WHERE Bedingung nur hinzufügen, wenn @Tags die datasätze hat.

Ist es möglich, eine WHERE-Bedingung nur hinzuzufügen, wenn meine Tabellenvariable datasätze ansonsten die gleiche Abfrage mit 1 = 1 (Immer wahr) und überspringen Sie den Kategorienfilter?

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 mnvalue('.[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 ) ) 

Letztlich musst du nur das Ende deiner Abfrage ändern. Wenn performance ein Problem ist, möchten Sie vielleicht zwei Zweige eines if Blocks für jeden der beiden Fälle in Betracht ziehen, obwohl es technisch möglich ist, die Logik in eine einzige Abfrage zu quetschen, die sich auch nicht generell optimiert.

 AND ( C.CategoryId IN ( SELECT CategoryId FROM CategotryXTag WHERE TagId IN ( SELECT TagId FROM @Tags ) ) OR (SELECT COUNT(*) FROM @Tags) = 0 ) 
 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; 

Wenn @tags leer ist, musst du vielleicht einen datasatz mit einem Wert setzen, der niemals verwendet würde und dann oder diesen Wert

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

Du musst deine where Klausel nicht ändern. Stattdessen erreichen Sie die gleiche Logik, indem Sie @Tags mit jedem TagId aus CategoryXTag TagId bevor Sie Ihre endgültige Abfrage @Tags wenn @Tags nach dem ersten Einfügen leer ist:

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

Ich würde eine Variable für die @Tags-Tabelle deklarieren:

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

und ändere die wo klausel wie

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

COUNT (*) ist langsamer. Der Nachteil des Hinzufügens der Zählung / existiert direkt zu Ihrer ursprünglichen Abfrage ist, dass SQL-server es für alle Zeilen ausführen könnte.