Подтвердить что ты не робот

Почему я не могу использовать псевдоним для агрегата в условии наличия?

Мой код выглядит так:

select col1,count(col2) as col7
from --some join operation
group by col1
having col7 >= 3 -- replace col7 by count(col2) to make the code work

Мой код вызывает ошибку "Недопустимое имя столбца" col7 ". Почему это происходит? Кажется нелогичным, что SQL не позволяет мне использовать col7 в последней строке.

Я использую SQL Server express 2008

4b9b3361

Ответ 1

В MS SQL единственное место (я знаю), что вы можете ссылаться на псевдонимы, находится в предложении ORDER BY. Возможность ссылаться на псевдонимы в других частях запроса - это функция, которой обладают многие другие платформы db, и, честно говоря, она раздражает меня тем, что Microsoft не считает ее достаточно полезной функцией для ее добавления.

Ответ 2

Предложение HAVING оценивается до SELECT поэтому сервер еще не знает об этом псевдониме.

  1. Сначала формируется произведение всех таблиц в предложении FROM.

  2. Затем выполняется предложение WHERE чтобы исключить строки, которые не удовлетворяют условию search_condition.

  3. Затем строки группируются с использованием столбцов в предложении GROUP BY.

  4. Затем группы, которые не удовлетворяют search_condition в предложении HAVING, удаляются.

  5. Затем оцениваются выражения в целевом списке SELECT.

  6. Если ключевое слово DISTINCT присутствует в предложении select, дублирующиеся строки теперь удаляются.

  7. UNION берется после каждого подвыбора.

  8. Наконец, результирующие строки сортируются в соответствии со столбцами, указанными в предложении ORDER BY.

  9. Предложение TOP выполнено.

Надеюсь, что это ответ на ваш вопрос. Также объясняется, почему псевдоним работает в предложении ORDER BY.

Ответ 3

Попробуйте с этим, так как список выбора содержит одно и то же выражение, которое вы можете использовать и в условии:

SELECT COL1,COUNT(COL2) AS COL7
FROM --SOME JOIN OPERATION
GROUP BY COL1
HAVING COUNT(COL2) >= 3 

Ответ 4

Вы должны выбрать дважды, чтобы использовать столбец count()

select * from (select col1,count(col2) as col7
from --some join operation
group by col1) as temp
where temp.col7 >= 3

Ответ 5

U может использовать этот код:

IF OBJECT_ID('tempdb..#temp') is not null DROP TABLE #temp

-- Create tempurary table
CREATE TABLE #temp (Id BIGINT IDENTITY(1,1), col1 BIGINT, countOfcol2 BIGIN)

--insert from the table 2 #temp
INSERT INTO #temp (col1,countOfcol2) 

select col1,count(col2) as col7
from --some join operation

select col1,countOfcol2 from #temp
group by col1
having countOfcol2 >= 3 -- replace col7 by count(col2) to make the code work

Ответ 6

Вы можете решить это с помощью вложенного запроса.

Я также столкнулся с этой проблемой, когда я хочу улучшить производительность. Мне нужно было запустить count() на основе определенных полей в пределах поля JSON в таблице, очевидно, что мы хотели бы проанализировать JSON только один раз, вместо того, чтобы включать отдельный счетчик в предложение where или have (особенно дорогой, такой как в моем случае).

Если col1 является уникальным идентификатором, самый эффективный в вычислительном отношении способ может заключаться во вложении счетчика в отдельный select

select col1, innerquery.col7
from whatevertable
inner join (select col1, count(col2) as col7 
            from whatevertable 
            group by col1) as innerquery 
            on innerquery.col1 = whatevertable.col1
where innerquery.col7 >= 3;

Таким образом, счетчик запускается только один раз, создавая временную таблицу поиска для справки по остальной части вашего запроса.

Опять же, это работает только в том случае, если col1 уникален для каждой записи, что обычно не слишком много, чтобы спросить, так как большинство таблиц имеют своего рода первичный ключ id.

Ответ 7

выберите col1, count (col2) как col7 от операции соединим группа по col1 имея count (col2) >= 3;

Честно говоря, я удивлен, почему SQL Server не обрабатывает псевдоним столбца. Я использую это как обходной путь. Он по-прежнему печатает имя столбца в качестве псевдонима, но обрабатывает исходную функцию агрегата.