使用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 76TrackTypeId 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 来进行此类查询。