2012-05-25 23 views
25

Por qué es que en SQL Server no puedo hacer esto:¿Por qué no puedo realizar una función de agregado en una expresión que contenga un agregado, pero puedo hacerlo creando una nueva instrucción de selección a su alrededor?

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

Pero no puedo hacer

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

¿No son esencialmente la misma cosa? ¿Cómo debo pensar en esto para entender por qué el primer bloque de código no está permitido?

+1

La primera manera también debería funcionar. ¿Cuál es el error que estás recibiendo? – dasblinkenlight

+0

@Michael se preocupa por compartir el error que está recibiendo cuando ejecuta el primer sql. Debería funcionar bien. –

+4

Un agregado escalar (No 'GROUP BY') siempre devuelve exactamente una fila. ¿Bajo qué circunstancias tendría sentido aplicar un agregado a esa fila? Un agregado vectorial devuelve una fila por grupo. Aunque a veces podría ser útil aplicar otra agregación al resultado de eso, necesitaría un diferente 'GROUP BY 'aplicado para los dos agregados para que esto sea útil. –

Respuesta

12

SUM() en su ejemplo es un no-op - SUMA() de un COUNT() significa lo mismo que simplemente COUNT(). Por lo tanto, ninguna de sus consultas de ejemplo parece hacer nada útil.

Me parece que los agregados de anidamiento solo tendrían sentido si quisiera aplicar dos agregaciones diferentes, es decir, GROUP BY en diferentes conjuntos de columnas. Para especificar dos agregaciones diferentes, deberá usar la función AGREGAR CONJUNTOS o SUMA() OVER. Tal vez si explicas lo que quieres lograr, alguien podría mostrarte cómo hacerlo.

+2

Tengo más curiosidad sobre por qué tengo que usar una tabla derivada para lograr esto: ¿por qué SQL Server no es compatible con mi primer ejemplo, pero sí con mi segundo? En esencia, me parecen lo mismo. Sin un propósito real, pidiendo educación. – Codingo

+0

@Michael El código SQL no permite SUM() con funciones agregadas.Si no lo permite, no se puede usar: P –

+2

@Michael, porque no habría forma en una sola instrucción SELECT de especificar diferentes agregaciones para las funciones anidadas y no tendría sentido si ambas funciones utilizan el mismo agregación. ¿Eso responde a la pregunta? – sqlvogel

1

Me funciona con SQLFiddle, no estoy seguro de por qué no funcionaría para usted. Pero tengo una explicación de por qué podría no funcionar para usted y por qué la alternativa funcionaría ...

Su ejemplo está utilizando una palabra clave como nombre de columna, que puede no funcionar siempre. Pero cuando la columna está solo en una sub-expresión, el motor de consulta puede descartar el nombre (de hecho lo hace probalmente), por lo que puede descartarse el hecho de que potencialmente entra en conflicto con una palabra clave.

EDIT: en respuesta a su edición/comentario. No, los dos no son equivalentes. El RESULTADO sería equivalente, pero el proceso para llegar a ese resultado no es para nada similar. Para que el primero funcione, el analizador realiza un trabajo que simplemente no tiene sentido (aplicando un agregado a un solo valor, ya sea fila por fila o como), en el segundo caso, un agregado se aplica a una mesa. El hecho de que la tabla sea una tabla virtual temporal no tendrá importancia para la función agregada.

+0

Disculpas, parece que cometí un error en la consulta original (primera). ¡Ahora corregido! – Codingo

-6

Microsoft SQL Server no lo admite.

Puede solucionar este problema mediante el uso de una mesa Derived:

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

Por otra parte utilizando el código de abajo le dará un mensaje de error.

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

No se puede realizar una función de agregado en una expresión que contiene un agregado o una subconsulta

+4

Esto solo reafirma la pregunta realmente. –

+0

@MartinSmith No, es un hecho que Issue se puede resolver usando la tabla derivada. – Nilish

+4

Un hecho que ya está indicado en la pregunta. El segundo ejemplo muestra que una tabla derivada funciona. La pregunta es ** ¿Por qué ** es este el caso? –

7

El quid de la cuestión es que no hay un concepto como el agregado de un agregado aplicado a una relación, vea Aggregation. Tener un concepto así dejaría demasiados agujeros en la definición y haría imposible expresar la cláusula GROUP BY: necesita definir tanto el agregado interno de la cláusula GROUP BY como el agregado externo también.Esto se aplica también a los otros atributos agregados, como la cláusula HAVING.

Sin embargo, el resultado de un agregado aplicado a una relación es otra relación, y esta relación de resultados a su vez puede admitir un nuevo operador agregado. Esto explica por qué puede agregar el resultado en un SELECT externo. Esto no deja ambigüedad en la definición, cada SELECT tiene sus propias cláusulas distintas GROUP BY/HAVING.

1

En términos simples, las funciones de agregación operan en una columna y generan un valor escalar, por lo que no se pueden aplicar sobre su resultado. Cuando crea una instrucción select sobre un valor escalar, transforma en una columna artificial, es por eso que puede ser utilizada por una función de agregación nuevamente.

Tenga en cuenta que la mayoría de las veces no tiene sentido aplicar una función de agregación sobre el resultado de otra función de agregación: en su muestra sum(count(id)) == count(id).

1

me gustaría saber cuál es su resultado esperado en este sql

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

cuando se utiliza la función de count, sólo el 1 resultado (recuento total) será el retorno. Entonces, ¿puedo preguntar por qué quieres sumar el único resultado?

Seguramente obtendrá el error porque una función de agregado no puede funcionar en una expresión que contenga un agregado o una subconsulta.

-1

Creo que puede escribir la consulta sql, que produce 'conteo' de filas para la salida requerida. Las funciones no toman funciones agregadas como 'suma' o subconsulta agregada. Mi problema se resolvió mediante el uso de una consulta sql simple para obtener el conteo ...

Cuestiones relacionadas