我有以下查询从表变量中获取TagId列表并返回列表。
但是,只有@Tags有记录时才需要添加CategoryId WHERE条件。
是否可以仅在我的表变量有记录时添加WHERE条件,否则运行相同的查询1 = 1(始终为真)并跳过类别过滤器?
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
)
)
答案 0 :(得分:1)
let balance =
makeInitialDeposit OneDollarBill
|> logToFile "file.txt" (sprintf "Initial Deposit: %A")
|> totalValue
|> logToFile "file2.txt" (sprintf "Balance : $%M")
如果@tags为空,您可能需要在其中放入一条记录,其中的值永远不会被使用然后或该值
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;
答案 1 :(得分:1)
最终,您只需要更改查询的结尾。如果性能是一个问题,您可能需要考虑为这两种情况中的每一种使用if
块的两个分支,即使它在技术上可以将逻辑压缩到单个查询中并不是通常也会优化。
AND
(
C.CategoryId IN (
SELECT CategoryId
FROM CategotryXTag
WHERE TagId IN (
SELECT TagId
FROM @Tags
)
)
OR
(SELECT COUNT(*) FROM @Tags) = 0
)
答案 2 :(得分:1)
您不需要修改where
条款。相反,如果在初始插入后@Tags
为空,则在运行最终查询之前,通过从TagId
填充CategoryXTag
@Tags
来实现相同的逻辑:
if ((select count(*) from @Tags) = 0)
insert into @Tags
select distinct TagId
from CategoryXTag;
答案 3 :(得分: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 / exists直接添加到原始查询的缺点是SQL Server可能会为所有行执行它。