functions sql oracle group-by aggregate-functions

sql - functions - oracle group by having



GROUP BY sin funciĆ³n agregada (9)

Así es como funciona GROUP BY. Toma varias filas y las convierte en una fila. Debido a esto, tiene que saber qué hacer con todas las filas combinadas donde hay diferentes valores para algunas columnas (campos). Esta es la razón por la que tiene dos opciones para cada campo que desea SELECCIONAR: o incluirlo en la cláusula GROUP BY, o usarlo en una función agregada para que el sistema sepa cómo desea combinar el campo.

Por ejemplo, digamos que tienes esta tabla:

Name | OrderNumber ------------------ John | 1 John | 2

Si dices GROUP BY Name, ¿cómo sabrá qué OrderNumber mostrar en el resultado? Entonces, puede incluir OrderNumber en group by, lo que dará como resultado estas dos filas. O bien, usa una función agregada para mostrar cómo manejar los OrderNumbers. Por ejemplo, MAX(OrderNumber) , lo que significa que el resultado es John | 2 John | 2 o SUM(OrderNumber) que significa que el resultado es John | 3 John | 3 .

Estoy intentando entender GROUP BY (nuevo en Oracle dbms) sin función agregada.
¿Cómo funciona?
Esto es lo que he intentado.

Tabla EMP en la que ejecutaré mi SQL.

SELECT ename , sal FROM emp GROUP BY ename , sal

SELECT ename , sal FROM emp GROUP BY ename;

Resultado

ORA-00979: no es una expresión GROUP BY
00979. 00000 - "no es una expresión GROUP BY"
*Porque:
*Acción:
Error en la línea: 397 Columna: 16

SELECT ename , sal FROM emp GROUP BY sal;

Resultado

ORA-00979: no es una expresión GROUP BY
00979. 00000 - "no es una expresión GROUP BY"
*Porque:
* Acción: Error en la línea: 411 Columna: 8

SELECT empno , ename , sal FROM emp GROUP BY sal , ename;

Resultado

ORA-00979: no es una expresión GROUP BY
00979. 00000 - "no es una expresión GROUP BY"
*Porque:
* Acción: Error en la línea: 425 Columna: 8

SELECT empno , ename , sal FROM emp GROUP BY empno , ename , sal;

Entonces, básicamente, el número de columnas tiene que ser igual al número de columnas en la cláusula GROUP BY, pero todavía no entiendo por qué o qué está sucediendo.


Como una adición

básicamente, el número de columnas debe ser igual al número de columnas en la cláusula GROUP BY

no es una declaración correcta.

  • Cualquier atributo que no sea parte de la cláusula GROUP BY no se puede usar para la selección
  • Cualquier atributo que sea parte de la cláusula GROUP BY se puede usar para la selección pero no es obligatorio.

Déjame dar algunos ejemplos.

Considera esta información.

CREATE TABLE DATASET ( VAL1 CHAR ( 1 CHAR ), VAL2 VARCHAR2 ( 10 CHAR ), VAL3 NUMBER ); INSERT INTO DATASET ( VAL1, VAL2, VAL3 ) VALUES ( ''b'', ''b-details'', 2 ); INSERT INTO DATASET ( VAL1, VAL2, VAL3 ) VALUES ( ''a'', ''a-details'', 1 ); INSERT INTO DATASET ( VAL1, VAL2, VAL3 ) VALUES ( ''c'', ''c-details'', 3 ); INSERT INTO DATASET ( VAL1, VAL2, VAL3 ) VALUES ( ''a'', ''dup'', 4 ); INSERT INTO DATASET ( VAL1, VAL2, VAL3 ) VALUES ( ''c'', ''c-details'', 5 ); COMMIT;

¿Qué hay en la mesa ahora?

SELECT * FROM DATASET; VAL1 VAL2 VAL3 ---- ---------- ---------- b b-details 2 a a-details 1 c c-details 3 a dup 4 c c-details 5 5 rows selected.

--agregar con grupo por

SELECT VAL1, COUNT ( * ) FROM DATASET A GROUP BY VAL1; VAL1 COUNT(*) ---- ---------- b 1 a 2 c 2 3 rows selected.

--agregar con grupo por columnas múltiples, pero seleccionar columna parcial

SELECT VAL1, COUNT ( * ) FROM DATASET A GROUP BY VAL1, VAL2; VAL1 ---- b c a a 4 rows selected.

- Sin agregado con grupo por múltiples columnas

SELECT VAL1, VAL2 FROM DATASET A GROUP BY VAL1, VAL2; VAL1 ---- b b-details c c-details a dup a a-details 4 rows selected.

- Sin agregado con grupo por múltiples columnas

SELECT VAL1 FROM DATASET A GROUP BY VAL1, VAL2; VAL1 ---- b c a a 4 rows selected.

Tiene N columnas en seleccionar (excluyendo agregaciones), entonces debe tener N o N + x columnas


El único caso de uso real para GROUP BY sin agregación es cuando GROUP BY más columnas que están seleccionadas, en cuyo caso las columnas seleccionadas pueden repetirse. De lo contrario, también podría utilizar un DISTINCT.

Vale la pena señalar que otros RDBMS no requieren que todas las columnas no agregadas se incluyan en GROUP BY. Por ejemplo, en PostgreSQL si las columnas de clave primaria de una tabla están incluidas en GROUP BY, entonces no es necesario que haya otras columnas de esa tabla, ya que se garantiza que serán distintas para cada columna de clave principal distinta. He deseado en el pasado que Oracle hiciera lo mismo que hubiera hecho para SQL más compacto en muchos casos.


Está experimentando un requisito estricto de la cláusula GROUP BY. Cada columna que no está en la cláusula group-by debe tener una función aplicada para reducir todos los registros del "grupo" correspondiente a un solo registro (suma, máximo, mínimo, etc.).

Si enumera todas las columnas consultadas (seleccionadas) en la cláusula GROUP BY, esencialmente está solicitando que los registros duplicados se excluyan del conjunto de resultados. Eso da el mismo efecto que SELECT DISTINCT, que también elimina filas duplicadas del conjunto de resultados.


Sé que dijiste que quieres entender al grupo por si tienes datos como este:

COL-A COL-B COL-C COL-D 1 Ac C1 D1 2 Bd C2 D2 3 Ba C1 D3 4 Ab C1 D4 5 C C2 D5

Y desea hacer que los datos aparezcan como:

COL-A COL-B COL-C COL-D 4 Ab C1 D4 1 Ac C1 D1 3 Ba C1 D3 2 Bd C2 D2 5 C C2 D5

Tu usas:

select * from table_name order by col-c,colb

Porque creo que esto es lo que intentas hacer.


Si tiene alguna columna en la cláusula SELECT, ¿cómo la seleccionará si hay varias filas? así que sí, cada columna en la cláusula SELECT debería estar en la cláusula GROUP BY también, puedes usar funciones agregadas en SELECT ...

puede tener una columna en la cláusula GROUP BY que no está en la cláusula SELECT, pero de lo contrario no


Teniendo en cuenta esta información:

Col1 Col2 Col3 A X 1 A Y 2 A Y 3 B X 0 B Y 3 B Z 1

Esta consulta

SELECT Col1, Col2, Col3 FROM data GROUP BY Col1, Col2, Col3

Daría como resultado exactamente la misma tabla.

Sin embargo, esta consulta:

SELECT Col1, Col2 FROM data GROUP BY Col1, Col2

Daría lugar a

Col1 Col2 A X A Y B X B Y B Z

Ahora, una consulta:

SELECT Col1, Col2, Col3 FROM data GROUP BY Col1, Col2

Crearía un problema: la línea con A, Y es el resultado de agrupar las dos líneas

A Y 2 A Y 3

Entonces, ¿qué valor debería estar en Col3, ''2'' o ''3''?

Normalmente usarías un grupo para calcular, por ejemplo, una suma:

SELECT Col1, Col2, SUM(Col3) FROM data GROUP BY Col1, Col2

Entonces en la línea que tuvimos un problema ahora obtenemos (2 + 3) = 5.

Agrupar por todas sus columnas en su selección es efectivamente lo mismo que usar DISTINCT, y es preferible usar la lectura de palabra clave DISTINCT en este caso.

Entonces, en lugar de

SELECT Col1, Col2, Col3 FROM data GROUP BY Col1, Col2, Col3

utilizar

SELECT DINSTINCT Col1, Col2, Col3 FROM data


Utilice la sub consulta, por ejemplo:

SELECT field1,field2,(SELECT distinct field3 FROM tbl2 WHERE criteria) AS field3 FROM tbl1 GROUP BY field1,field2

O

SELECT DISTINCT field1,field2,(SELECT distinct field3 FROM tbl2 WHERE criteria) AS field3 FROM tbl1