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

Почему я не могу выполнить агрегированную функцию в выражении, содержащем агрегат, но я могу сделать это, создав вокруг него новый оператор select?

Почему в SQL Server я не могу этого сделать:

select  sum(count(id)) as 'count'
from    table

Но я могу сделать

select sum(x.count)
from
(
    select  count(id) as 'count'
    from    table   
) x

Разве это не одно и то же? Как я должен думать об этом, чтобы понять, почему первый блок кода не разрешен?

4b9b3361

Ответ 1

SUM() в вашем примере является no-op - SUM() для COUNT() означает то же самое, что и COUNT(). Поэтому ни один из ваших примерных запросов не делает ничего полезного.

Мне кажется, что вложенные агрегаты имели бы смысл только в том случае, если бы вы хотели применить две разные агрегирования - то есть GROUP BY для разных наборов столбцов. Чтобы указать два разных агрегата, вам нужно будет использовать функцию GROUPING SETS или функцию SUM() OVER. Может быть, если вы объясните, чего вы хотите достичь, кто-то может показать вам, как это сделать.

Ответ 2

Суть проблемы заключается в том, что нет такой концепции, как совокупность совокупности, применяемой к отношению, см. Aggregation. Наличие такого понятия оставляет слишком много дыр в определении и делает предложение GROUP BY невозможным для выражения: ему нужно также определить как внутреннее агрегированное предложение GROUP BY, так и внешний агрегат! Это относится также к другим агрегированным атрибутам, таким как предложение HAVING.

Однако результатом агрегирования, применяемого к отношению, является другое отношение, и это отношение результата в свою очередь может поддерживать новый агрегированный оператор. Это объясняет, почему вы можете агрегировать результат во внешний SELECT. Это не оставляет двусмысленности в определении, каждый SELECT имеет свои собственные отдельные предложения GROUP BY/HAVING.

Ответ 3

Он работает для меня, используя SQLFiddle, не зная, почему это не сработает для вас. Но у меня есть объяснение, почему это может не работать для вас и почему альтернатива будет работать...

В вашем примере используется ключевое слово в качестве имени столбца, которое может не всегда работать. Но когда столбец находится только в подвыражении, механизм запроса может отбросить имя (на самом деле это просто так), так что тот факт, что он потенциально потенциально конфликтует с ключевым словом, может быть проигнорирован.

EDIT: в ответ на ваше изменение/комментарий. Нет, они не эквивалентны. РЕЗУЛЬТАТ был бы эквивалентен, но процесс достижения этого результата совсем не похож. Для того, чтобы первый работал, анализатор выполнил некоторую работу, которая просто не имеет смысла для этого (с применением совокупности к одному значению, либо по строке за строкой, либо как), во втором случае - совокупность применяется к таблице. Тот факт, что таблица является временной виртуальной таблицей, будет неважна для агрегатной функции.

Ответ 4

В простых терминах функции агрегации работают над столбцом и генерируют скалярное значение, поэтому они не могут применяться к их результату. Когда вы создаете оператор select над скалярным значением, вы преобразуете его в искусственный столбец, поэтому его можно снова использовать функцией агрегации.

Обратите внимание, что в большинстве случаев нет смысла применять функцию агрегирования к результату другой функции агрегации: в вашем примере sum(count(id)) == count(id).

Ответ 5

Мне бы хотелось узнать, что ваш ожидаемый результат в этом sql

select  sum(count(id)) as 'count'
from    table

когда вы используете функцию count, возвращается только 1 результат (общее количество). Итак, могу ли я спросить, почему вы хотите суммировать только один результат.

Вы обязательно получите ошибку, потому что агрегатная функция не может выполнять выражение, содержащее агрегат или подзапрос.

Ответ 6

Я думаю, вы можете написать sql-запрос, который производит "подсчет" строк для требуемого вывода. Функции не выполняют агрегированные функции, такие как "сумма" или агрегированный подзапрос. Моя проблема была решена с помощью простого SQL-запроса, чтобы получить счет.

Ответ 7

Microsoft SQL Server не поддерживает его.

Вы можете обойти эту проблему, используя таблицу Derived:

select sum(x.count)
from
(
    select  count(id) as 'count'
    from    table   
) x

С другой стороны, используя приведенный ниже код, вы получите сообщение об ошибке.

select  sum(count(id)) as 'count'
from    table

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