使用udt忽略搜索查询中的空值
Ignore null in search query using udt
我正在研究过滤功能,但我正在为 Sql 苦苦挣扎。
我有一个符合这种逻辑的程序。
RIGHT JOIN @filterQuery as fq
ON (fq.Bpm = c.BPM OR fq.Bpm IS NULL)
AND (fq.Price >= c.Price OR fq.Price IS NULL)
AND (fq.GenreTypeId = g.Id OR fq.GenreTypeId IS NULL)
AND (fq.KeyTypeId = k.Id OR fq.KeyTypeId IS NULL)
AND (fq.TrackTypeId = t.Id OR fq.TrackTypeId IS NULL)
我的测试代码是这样的
DECLARE @filters AS dbo.FilterTable
,@PageIndex int = 0
,@PageSize int = 10
INSERT INTO @filters (Bpm,Price,GenreTypeId,KeyTypeId,TrackTypeId)
VALUES (126,null,null,null,null),(76,null,null,null,2)
EXECUTE dbo.PROC @filters
,@PageIndex
,@PageSize
现在我的问题是,当我 运行 我的代码时,我的结果集看起来像这样。
Bpm Price GenreTypeId KeyTypeId TrackTypeId
126 5.99 1 1 1
126 4.99 1 1 1
这是有道理的,因为没有 BPM 76 和 TrackTypeId 2 但因为 BPM 126 的第一组值在 TrackTypeId 它不会从第二组值中筛选 TrackTypeId 2。
我需要我的结果集是 empty 因为数据库中没有 records any TrackTypeId 2。这可能吗?
编辑:我希望我的结果集为空,因为没有带有 trackTypeId 2 的数据。但目前它给了我所有 126 BPM,因为对于这个特定的过滤器,trackTypeId 为空。
根据您要实现的逻辑判断,您需要的是每个筛选列单独的 table 类型。 您还应该具有以下样式的逻辑
WHERE (NOT EXISTS (SELECT 1 FROM @columnFilters) OR column IN (SELECT * FROM @columnFilters))
出于这种目的,我通常在数据库中保留一些标准的单列 table 类型的各种数据类型。
WHERE (NOT EXISTS (SELECT 1 FROM @Bpm) OR
c.Bpm IN (SELECT * FROM @Bpm))
AND (c.Price >= @Price OR @Price IS NULL)
AND (NOT EXISTS (SELECT 1 FROM @GenreTypeId) OR
g.Id IN (SELECT * FROM @GenreTypeId))
AND (NOT EXISTS (SELECT 1 FROM @KeyTypeId) OR
k.Id IN (SELECT * FROM @KeyTypeId))
AND (NOT EXISTS (SELECT 1 FROM @TrackTypeId) OR
t.Id IN (SELECT * FROM @TrackTypeId))
请注意 @Price
的标量变量的使用,因为您可以只输入您想要的最小值,因为条件是不等式 >=
.
如果您确实也想为此使用 table,您可以这样做:
(NOT EXISTS (SELECT 1 FROM @Price) OR
c.Price >= ANY(SELECT * FROM @GenreTypeId))
如果您尝试访问索引,我强烈建议您查看 OPTION(RECOMPILE)
或动态 SQL 来进行此类查询。
我正在研究过滤功能,但我正在为 Sql 苦苦挣扎。
我有一个符合这种逻辑的程序。
RIGHT JOIN @filterQuery as fq
ON (fq.Bpm = c.BPM OR fq.Bpm IS NULL)
AND (fq.Price >= c.Price OR fq.Price IS NULL)
AND (fq.GenreTypeId = g.Id OR fq.GenreTypeId IS NULL)
AND (fq.KeyTypeId = k.Id OR fq.KeyTypeId IS NULL)
AND (fq.TrackTypeId = t.Id OR fq.TrackTypeId IS NULL)
我的测试代码是这样的
DECLARE @filters AS dbo.FilterTable
,@PageIndex int = 0
,@PageSize int = 10
INSERT INTO @filters (Bpm,Price,GenreTypeId,KeyTypeId,TrackTypeId)
VALUES (126,null,null,null,null),(76,null,null,null,2)
EXECUTE dbo.PROC @filters
,@PageIndex
,@PageSize
现在我的问题是,当我 运行 我的代码时,我的结果集看起来像这样。
Bpm Price GenreTypeId KeyTypeId TrackTypeId
126 5.99 1 1 1
126 4.99 1 1 1
这是有道理的,因为没有 BPM 76 和 TrackTypeId 2 但因为 BPM 126 的第一组值在 TrackTypeId 它不会从第二组值中筛选 TrackTypeId 2。
我需要我的结果集是 empty 因为数据库中没有 records any TrackTypeId 2。这可能吗?
编辑:我希望我的结果集为空,因为没有带有 trackTypeId 2 的数据。但目前它给了我所有 126 BPM,因为对于这个特定的过滤器,trackTypeId 为空。
根据您要实现的逻辑判断,您需要的是每个筛选列单独的 table 类型。 您还应该具有以下样式的逻辑
WHERE (NOT EXISTS (SELECT 1 FROM @columnFilters) OR column IN (SELECT * FROM @columnFilters))
出于这种目的,我通常在数据库中保留一些标准的单列 table 类型的各种数据类型。
WHERE (NOT EXISTS (SELECT 1 FROM @Bpm) OR
c.Bpm IN (SELECT * FROM @Bpm))
AND (c.Price >= @Price OR @Price IS NULL)
AND (NOT EXISTS (SELECT 1 FROM @GenreTypeId) OR
g.Id IN (SELECT * FROM @GenreTypeId))
AND (NOT EXISTS (SELECT 1 FROM @KeyTypeId) OR
k.Id IN (SELECT * FROM @KeyTypeId))
AND (NOT EXISTS (SELECT 1 FROM @TrackTypeId) OR
t.Id IN (SELECT * FROM @TrackTypeId))
请注意 @Price
的标量变量的使用,因为您可以只输入您想要的最小值,因为条件是不等式 >=
.
如果您确实也想为此使用 table,您可以这样做:
(NOT EXISTS (SELECT 1 FROM @Price) OR
c.Price >= ANY(SELECT * FROM @GenreTypeId))
如果您尝试访问索引,我强烈建议您查看 OPTION(RECOMPILE)
或动态 SQL 来进行此类查询。