【问题标题】:Xor between two conditions in SQL ServerSQL Server 中两个条件之间的异或
【发布时间】:2020-12-11 06:00:24
【问题描述】:

T-SQL 中有ORAND 运算符。 AND 表示两个条件都为真,OR 表示只有第一个条件为真、只有第二个条件为真或两个条件都为真。

但我需要XOR 之类的东西,它类似于OR,但如果两者都为真,则不应用WHERE 条件。

例子:

select * 
from [Table] 
where Id in (@FromId) XOR TypeId = @TypeId

我的问题是:我应该如何编写这个查询,所以如果找到Id in (@FromId),它不会检查TypeId =@TypeId,如果找不到Id in (@FromId),它会检查TypeId =@TypeId

我知道我可以写这个来解决问题:

select * from [Table] where Id in (@FromId) 
if @@ROWCOUNT =0
select * from  [Table] where TypeId =@TypeId

但我想把它写在一个查询中,为了简单、性能、更少的代码......

提前致谢。

【问题讨论】:

  • 这些查询在逻辑上并不相同。
  • 究竟是什么意思?你能解释更多吗?
  • 添加表 DDL 示例数据和所需结果,您可能会看到。
  • 如果你读过,我想你应该再读一遍。 SQL 查询的最小可重现示例:向我们展示 CREATE TABLEINSERT 语句,其中包含足够的样本数据以涵盖所有用例(满足一个条件的行、满足另一个条件的行、同时满足这两个条件的行,以及一行都不满足),然后告诉我们结果应该是每种情况。

标签: sql sql-server subquery where-clause window-functions


【解决方案1】:

sql server 中的 XOR 是 ^。请试一试

【讨论】:

    【解决方案2】:

    XOR 基本上可以用 AND 和 OR 表示如下:

     (cond1 AND NOT cond2) OR (NOT cond1 AND cond2)
    

    所以你的查询可以写成

    select * 
    from [Table] 
    where (Id in (@FromId) AND TypeId <> @TypeId) OR (Id NOT IN (@FromId) AND TypeId = @TypeId)
    

    【讨论】:

      【解决方案3】:

      我对此并不疯狂,但是...

      if exists(select * from [Table] where Id in (@FromId)) begin
          select * from [Table] where Id in (@FromId)
      end
      else begin
          select * from [Table] where TypeId = @TypeId
      end
      

      @FromId 是 CSV 还是其他可迭代实体?我会将其转换为表并加入,而不是使用 IN 运算符并遭受性能损失。

      【讨论】:

      • 感谢您的回复。但我认为有问题的代码主体更好,因为在您的代码中,在最坏的情况下我们有 3 个选择,但在我的代码中只有两个。
      【解决方案4】:

      您可以使用窗口函数在单个查询中执行此操作:

      select t.*
      from (
          select t.*, max(case when id in (@FromId) then 1 else 0 end) has_from_id
          from mytable t
      ) t
      where id in (@FromId) or (has_from_id = 0 and typeId = @typeId)
      

      另一种典型的做法是union allnot exists

      select t.*
      from mytable t
      where id in (@FromId)
      union all
      select t.*
      from mytable t
      where 
          typeId = @typeId
          and not exists (select 1 from mytable where id in (@FromId))
      

      【讨论】:

      • 谢谢,但是性能呢???我需要简单、性能、更少的代码
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-08-01
      • 1970-01-01
      • 2021-08-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多