【问题标题】:How to properly apply filter for the query presented?如何为呈现的查询正确应用过滤器?
【发布时间】:2023-03-20 14:12:01
【问题描述】:

我有一张桌子如下

declare @t table(bucket bigint null)

insert into @t select 1 union all select 2 union all select -1 union all select 5

现在让我编写下面的查询(按 Bucket 0 过滤 - 所有值都来了)

declare @Bucket bigint = 0 –filter by 0

select * from @t
where 1=1
AND (@Bucket is Null or @Bucket ='' or bucket=@Bucket)

Result
1
2
-1
5

但如果我按 2 或任何其他值过滤 Bucket,我会正确得到结果

declare @Bucket bigint = 2 –filter by 2
select * from @t
where 1=1
AND (@Bucket is Null or @Bucket ='' or bucket=@Bucket)

Result
2

如果我按 null 或空白过滤,我会得到正确的结果

declare @Bucket bigint = '' –filter by ''

select * from @t
where 1=1
AND (@Bucket is Null or @Bucket ='' or bucket=@Bucket)

Result
1
2
-1
5

为什么桶 0 会有这种行为?又该如何解决?

【问题讨论】:

    标签: sql sql-server tsql parameters


    【解决方案1】:

    您可以尝试使用@Bucket bigint = NULL 作为@Bucket 的默认值。

    因为NULL意味着不知道

    或者您可以设置一个不应在bucket 列中作为默认值的值。

    declare @Bucket bigint = NULL
    
    select * 
    from @t
    where (@Bucket is Null or bucket = @Bucket)
    

    注意

    但如果 @Bucket bigint 是 bigint,它不应该是 ''


    编辑

    CREATE TABLE T(
       Bucket bigint
    );
    
    declare @Bucket bigint = 0
    
    INSERT INTO T VALUES (1);
    INSERT INTO T VALUES (2);
    INSERT INTO T VALUES (-1);
    INSERT INTO T VALUES (5);
    INSERT INTO T VALUES (0);
    
    
    select * from T
    where  (@Bucket is Null or (@Bucket ='' and @Bucket <> 0)  or bucket=@Bucket)
    

    【讨论】:

    • 在 db 存储桶中被声明为 BigInt。并且应用程序正在发送空白('')。我无法改变其中任何一个。我已经尝试过您提出的查询。如果我们不能更改现有的 DB 或 FE 值,还有其他方法吗?
    • 为了让您更好地理解,请考虑这个存储过程: -- exec usp_mysp '','','','','','0',''。它将以动态方式运行。声明是 ALTER PROCEDURE [dbo].[usp_mysp] ( @Product NVARCHAR(200) = '' ,@Region NVARCHAR(100) = '' ,@State NVARCHAR(100) = '' ,@City NVARCHAR(100) = '' ,@Branch NVARCHAR(100) = '' ,@Bucket bigint = NULL ,@Staff NVARCHAR(200) = '' )
    • 好的。但是如果我们按空白(''')或 null 过滤,我们应该得到所有的值。目前的查询没有这样做。休息好
    • 我建议你修改你的默认值,因为declare @Bucket bigint = ''隐式转换为0dbfiddle.uk/…
    • 或者你能接受让 Bucket 为 varchar declare @Bucket VARCHAR(50) = ''?
    【解决方案2】:

    已修复

    declare @t table(bucket bigint);
    
    INSERT INTO @t VALUES (1);
    INSERT INTO @t VALUES (2);
    INSERT INTO @t VALUES (-1);
    INSERT INTO @t VALUES (5);
    INSERT INTO @t VALUES (0);
    
    declare @Bucket bigint = 0 --filter by 0
    
    select * from @t
    where 1=1
    AND (@Bucket is Null or cast(@Bucket as nvarchar) = '' or bucket=@Bucket)
    

    【讨论】:

    • 如果我们按0过滤,就不会有任何记录。您的查询产生所有记录
    猜你喜欢
    • 1970-01-01
    • 2020-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-15
    • 1970-01-01
    • 2023-03-09
    • 2021-04-21
    相关资源
    最近更新 更多