当放在条件括号中时,AND和OR组合与单独放置时的区别

时间:2019-07-12 21:31:22

标签: sql sql-server

当我使用如下脚本时,得到的结果数量会有所不同:

select count(distinct(t1.ticketid)),t1.TicketStatus from ticket as t1
inner join Timepoint as t2 on t1.TicketID=t2. ticketid
where 
    t2.BuilderAnalystID=10 and t1.SubmissionDT >='04-01-2018'  AND
      (t1.TicketBuildStatusID<>12 OR
       t1.TicketBuildStatusID<>11 OR 
       t1.TicketBuildStatusID<>10
      )

当我像这样使用它时:

 select count(distinct(t1.ticketid)),t1.TicketStatus from ticket as t1
    inner join Timepoint as t2 on t1.TicketID=t2. ticketid
    where 
        t2.BuilderAnalystID=10 and t1.SubmissionDT >='04-01-2018'  AND
        t1.TicketBuildStatusID<>12 AND
        t1.TicketBuildStatusID<>11 AND 
        t1.TicketBuildStatusID<>10

有人可以告诉我为什么会有区别,对我来说逻辑是一样的! 谢谢

5 个答案:

答案 0 :(得分:3)

在您的示例中,这没有关系,因为您具有所有AND子句。也就是说,您需要了解优先级(即操作顺序),其中NOTAND之前,ANDOR之前,依此类推。

就像3 + 3 x 0表示3 +(3 x 0)一样,A或B和C表示A或(B和C),即使那不是您的意思。

因此,在混合使用AND和OR子句的情况下,这很重要。

考虑以下示例:

select *
from A, B
where A.id = B.id and A.family_code = 'ABC' or A.family_code = 'DEF'

我承认这是可怕的代码,但出于说明目的,请忍受。

您可能是这个意思

select *
from A, B
where A.id = B.id and (A.family_code = 'ABC' or A.family_code = 'DEF')

但是你这样说:

select *
from A, B
where (A.id = B.id and A.family_code = 'ABC') or A.family_code = 'DEF'

上面的构造完全破坏了您的联接,在所有家庭代码为DEF的情况下产生笛卡尔积。

因此,最重要的是:当您混合使用子句(AND,OR,NOT)时,即使不需要,也最好使用括号来明确说明您的意思。

令人回味的食物。

-编辑-

在我写完这篇文章后,问题就被改变了,以致查询不一样(并且将“ s”更改为“ ors”)。

希望我的解释仍然有用。

答案 1 :(得分:2)

编辑完您的问题后,现在会有所不同。

urchin_vs_recruitment_plot <- ggplot(data = urchin_vs_recruitment_summary_data, aes(x = urchin_mean, y = recruitment_mean, fill = Shelter, shape = Site_long)) + 
  ggtitle("Urchin Abundance vs Coral Recruitment") +
  geom_point(aes(size = 3)) +
  scale_shape_manual(values = c(21, 24)) +
  coord_cartesian(ylim = c(0,5)) +
  scale_fill_manual(values = c(NA, "black"), guide = guide_legend(override.aes = list(shape = 21))) +
  guides(size = FALSE) +
  theme(text = element_text(size = 15)) +
  geom_errorbar(aes(ymin = recruitment_lower, ymax = recruitment_upper), width = .6) + 
  geom_errorbarh(aes(xmin = urchin_lower, xmax = urchin_upper), height = .15) +
  labs(x = "Mean urchin abundance ± SEM", y = "Mean coral recruitment ± SEM") +
  theme_bw() + theme(panel.border = element_blank(), panel.grid.major = element_blank(), panel.grid.minor = element_blank(), axis.line = element_line(colour = "black"), axis.title = element_text(size = rel(1.5)), axis.text = element_text(size = rel(1.5)), legend.text = element_text(size = rel(1.5)), plot.title = element_text(size = 20, hjust = 0.5, vjust = -1.5), legend.position = c(.8, .8))

此查询将返回t2.BuilderAnalystID=10 and t1.SubmissionDT >='04-01-2018' AND (t1.TicketBuildStatusID<>12 OR t1.TicketBuildStatusID<>11 OR t1.TicketBuildStatusID<>10 ) 为10、11和12的值。它声明该值不应为10(所以11和12),也不能是11(所以10和11),或者不应该是10。 12(所以10和11)。

答案 2 :(得分:1)

是的,那些查询将产生不同的结果。实际上,第一个查询将返回TicketBuildStatusID的每个值,除非它的值为NULL

TicketBuildStatusID具有值或12时,没有具有值1112,因此表达式{{1 }}, 是真的。如果它的值为(t1.TicketBuildStatusID<>12 OR t1.TicketBuildStatusID<>11 OR t1.TicketBuildStatusID<>10),则除了11以外,其他所有可能的值也会再次适用(因为NULL = {expression}<>NULL是不正确的)

答案 3 :(得分:1)

执行此操作

 AND
      (t1.TicketBuildStatusID<>12 OR
       t1.TicketBuildStatusID<>11 OR 
       t1.TicketBuildStatusID<>10) 

您基本上不做任何过滤器,因为任何评估为true的条件都会使所有条件为e.i.

true AND (true or false or false) = true

执行此操作时,所有条件都应匹配,例如状态不应为12,11,10

 AND
        t1.TicketBuildStatusID<>12 AND
        t1.TicketBuildStatusID<>11 AND 
        t1.TicketBuildStatusID<>10

答案 4 :(得分:0)

OR不是您想要的逻辑。因为如果x = 12,则不是11。因此,所有值都与x <> 12 and x <> 11匹配。

因此,只需简单地逻辑并使用{​​{1}}:

not in

注意:

  • select count(distinct t1.ticketid), t1.TicketStatus from ticket t1 inner join Timepoint t2 on t1.TicketID = t2.ticketid where t2.BuilderAnalystID = 10 and t1.SubmissionDT >= '2018-04-01' and t1.TicketBuildStatusID not in (12, 11, 10) 不是函数,因此不需要在括号中放置以下表达式。
  • 使用标准日期格式。 “ YYYYMMDD”或“ YYYY-M-DD”。