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