2012-02-28 2 views
2

Я использую SQL Server 2005, и я обнаружил странное поведение предложения HAVING.Миф о поведении предложения HAVING

По определению пункт HAVING является предполагается работать на данных после он сгруппированных. Однако использование функции COUNT внутри предложения HAVING фактически применяется к данным перед их сгруппировкой.

Что мне здесь не хватает ???

Образец данных:

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) 

Запрос в вопросе:

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) 
+0

Я не понимаю, что вы говорите. Я получаю одну строку со значением '9'. Попробуйте здесь. http://data.stackexchange.com/stackoverflow/query/62661/group-by-having Или, возможно, я ** ** ** получаю то же, что и вы, и я просто не понимаю ваш вопрос. –

+0

@Mikael I * think * asker означает, что, поскольку каждая * группа * имеет только один 'A',' COUNT (A) 'для каждой группы всегда должен быть 1; поэтому строки '2' и' 3' не должны возвращать записи. – AakashM

+0

'count' - это агрегированная функция, которая учитывает вхождения для одной группы. В этом случае с '3' для значения' 9', и значение будет таким же, если вы используете его в списке полей или в условии наличия. 'having' фильтрует строки ** после **' group by', но когда вы делаете 'count' в предложении having, он подсчитывает агрегированные строки. –

ответ

5

Используя агрегатную функцию count не даст вам разные результаты, если вы используете его в списке полей или в имеющей п ,

очередная группа по по A:

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

Результат:

A   C 
----------- ----------- 
9   3 
10   1 
12   2 

Если вы используете 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 

Результат:

C 
----------- 
3 

Обновление:

От HAVING (Transact-SQL)

Задает условие поиска для группы или агрегата.

От COUNT (Transact-SQL)

Возвращает количество элементов в группе.

+0

Другой подход к подсчету всего набора результатов. http://stackoverflow.com/questions/5146978/count-number-of-records-returned-by-group-by – Costa

Смежные вопросы