关于HAVING子句行为的神话

Cos*_*sta 2 t-sql group-by sql-server-2005

我正在使用SQL Server 2005,我发现该HAVING子句的奇怪行为.

根据定义,该HAVING子句应该在分组处理数据.但是,COUNTHAVING子句中使用函数实际上是在对数据进行分组之前应用于数据.

我在这里失踪了什么?

样本数据:

DECLARE @ProductTypeIDsTable TABLE
(
    A INT
)

INSERT INTO @ProductTypeIDsTable(A) VALUES
(10),(12),(12),(9),(9),(9)

DECLARE @IDsTable TABLE
(
    B INT
)

INSERT INTO @IDsTable(B) VALUES
(9),(10),(12)
Run Code Online (Sandbox Code Playgroud)

有问题的查询:

SELECT A 
    FROM @ProductTypeIDsTable pt 
    INNER JOIN @IDsTable ids ON pt.A = ids.B
    GROUP BY A
    --HAVING COUNT (A) = 1 -- gives 10 (repeated once due to the join)
    --HAVING COUNT (A) = 2 -- gives 12 (repeated twice due to the join)
    HAVING COUNT (A) = 3 -- gives 9 (repeated thrice due to the join)
Run Code Online (Sandbox Code Playgroud)

Mik*_*son 5

count如果在字段列表或having子句中使用聚合函数,则不会给出不同的结果.

一个常规小组A:

select pt.A, count(*) as C
from @ProductTypeIDsTable pt
  inner join @IDsTable as ids
    on pt.A = ids.B
group by pt.A
Run Code Online (Sandbox Code Playgroud)

结果:

A           C
----------- -----------
9           3
10          1
12          2
Run Code Online (Sandbox Code Playgroud)

如果您count在该having子句中使用此值,那么您将与之进行比较.

如果您对group by将查询放入子查询后返回的行数感兴趣,请执行以下操作:

select count(*) as C
from
  (
    select pt.A
    from @ProductTypeIDsTable pt
      inner join @IDsTable as ids
        on pt.A = ids.B
    group by pt.A
  ) as T
Run Code Online (Sandbox Code Playgroud)

结果:

C
-----------
3
Run Code Online (Sandbox Code Playgroud)

更新:

HAVING(Transact-SQL)

指定组或聚合的搜索条件.

来自COUNT(Transact-SQL)

返回组中的项目数.