首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用多列的组by和具有子句

使用多列的组by和具有子句
EN

Stack Overflow用户
提问于 2020-11-17 06:39:16
回答 2查看 653关注 0票数 1

下面的AND子句中的Having条件的行为就像它过滤行一样,即使当其中一个条件被满足时,它应该是逻辑的AND行为。

代码语言:javascript
复制
with cte as 
( select 'A' as name , 10 as Classes , 11 as Fees union all
 select 'A' as name , 10 as Classes , 10 as Fees union all
  select 'A' as name , 10 as Classes , 10 as Fees union all
   select 'A' as name , 10 as Classes , 10 as Fees union all
    select 'A' as name , 10 as Classes , 10 as Fees union all
     select 'B' as name , 0 as Classes , 10 as Fees union all
      select 'B' as name , 0 as Classes , 10 as Fees union all
       select 'B' as name , 1 as Classes , 10 as Fees union all
        select 'B' as name , -10 as Classes , 10 as Fees union all
         select 'B' as name , 10 as Classes , 11 as Fees 
       )
       -- A has 50 rooms and 51 $ -- so it should not be returned
       -- B has 1 room and 51 $ and should be fetched
        -- why would the AND in the having clause  behave like a row level filter on only the indivigual column 
        -- instead of the combination
        -- The weird thing is the logic behaves as expected when using = but fails when using <>
       select name , sum(Classes) , sUM(Fees)
       from cte 
       group by name 
       having ( SUM(Classes) !=50) AND (sum(Fees) !=51  )

下面是奇怪的部分,如果用下面所示的=替换!=,那么它工作得很好。

代码语言:javascript
复制
with cte as 
( select 'A' as name , 10 as Classes , 11 as Fees union all
 select 'A' as name , 10 as Classes , 10 as Fees union all
  select 'A' as name , 10 as Classes , 10 as Fees union all
   select 'A' as name , 10 as Classes , 10 as Fees union all
    select 'A' as name , 10 as Classes , 10 as Fees union all
     select 'B' as name , 0 as Classes , 10 as Fees union all
      select 'B' as name , 0 as Classes , 10 as Fees union all
       select 'B' as name , 1 as Classes , 10 as Fees union all
        select 'B' as name , -10 as Classes , 10 as Fees union all
         select 'B' as name , 10 as Classes , 11 as Fees 
       )
       -- A has 50 rooms and 51 $ -- so it should not be returned
       -- B has 1 room and 51 $ and should be fetched
        -- why would the AND in the having clause  behave like a row level filter on only the indivigual column 
        -- instead of the combination
        -- The weird thing is the logic behaves as expected when using = but fails when using <>
       select name , sum(Classes) , sUM(Fees)
       from cte 
       group by name 
       having ( SUM(Classes) =1) AND (sum(Fees) =51  )

当涉及到Group by的工作方式时,我是不是遗漏了什么?我知道我可以回避这个问题,但我不明白它为什么会这样。

这就是我得到的

这是我应该得到的

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-11-17 07:08:29

经过一些讨论后,试着使用这个

代码语言:javascript
复制
 having not(SUM(Classes) =50 AND sum(Fees) =51)

你写布尔值的时候要三思。

票数 1
EN

Stack Overflow用户

发布于 2020-11-17 07:09:31

你似乎不懂布尔逻辑。

如果没有those子句,这些就是您的结果。

代码语言:javascript
复制
A   50  51
B   1   51

使用

代码语言:javascript
复制
 having ( SUM(Classes) !=50) AND (sum(Fees) !=51  )

你问:给我看所有的行,哪些类不是50,哪些费用不是51。

和是重要的。

现在,再看看结果,没有子句,并问自己,你为什么会期待任何东西会被退回?

因为这两行都有一个fee=51,所以不会返回任何数据,因为您要求的行的费用与51不同。

这是一个已知的头脑陷阱,当您用AND累积NOT (或<> !=)时,它来自布尔逻辑。一般来说,你不应该这么做。当您有几个NOT时,您应该用OR、not和和累积它们。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64870424

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档