GROUP BY без агрегатной функции

Я пытаюсь понять GROUP BY (новый для оракула dbms) без агрегатной функции.
Как это работает?
Вот что я пробовал.

Таблица EMP, на которой я буду запускать свой SQL.
EMP TABLE

SELECT ename , sal
FROM emp
GROUP BY ename , sal

Result

SELECT ename , sal  
FROM emp  
GROUP BY ename;  

Результат

ORA-00979: не выражение GROUP BY
00979. 00000 - "не выражение GROUP BY"
* Причина:
* Действие:
Ошибка в строке: 397 Колонка: 16

SELECT ename , sal  
FROM emp  
GROUP BY sal;  

Результат

ORA-00979: не выражение GROUP BY
00979. 00000 - "не выражение GROUP BY"
* Причина:
* Действие: Ошибка в строке: 411 Колонка: 8

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

Результат

ORA-00979: не выражение GROUP BY
00979. 00000 - "не выражение GROUP BY"
* Причина:
* Действие: Ошибка в строке: 425 Колонка: 8

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

Result

Итак, в основном число столбцов должно быть равно числу столбцов в предложении GROUP BY, но я до сих пор не понимаю, почему и что происходит.

Ответы

Ответ 1

Как работает GROUP BY. Он занимает несколько строк и превращает их в одну строку. Из-за этого он должен знать, что делать со всеми объединенными строками, где для некоторых столбцов (полей) есть разные значения. Вот почему у вас есть два варианта для каждого поля, которое вы хотите выбрать: либо включить его в предложение GROUP BY, либо использовать его в агрегатной функции, чтобы система знала, как вы хотите объединить это поле.

Например, скажем, у вас есть эта таблица:

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

Если вы скажете "GROUP BY Name", как он узнает, какой номер OrderNumber будет показан в результате? Таким образом, вы либо включаете OrderNumber в группу, что приведет к этим двум строкам. Или вы используете агрегированную функцию, чтобы показать, как обрабатывать OrderNumbers. Например, MAX(OrderNumber), что означает результат John | 2 или SUM(OrderNumber), что означает, что результат John | 3.

Ответ 2

Вы испытываете строгое требование предложения GROUP BY. Каждый столбец, не содержащийся в предложении group-by, должен иметь функцию, применяемую для уменьшения всех записей для соответствующей "группы" до одной записи (сумма, макс, мин и т.д.).

Если вы укажете все столбцы запроса (выбранные) в предложении GROUP BY, вы по существу запрашиваете, чтобы дублирующие записи были исключены из набора результатов. Это дает тот же эффект, что и SELECT DISTINCT, который также исключает повторяющиеся строки из набора результатов.

Ответ 3

Учитывая эти данные:

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

Этот запрос

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

Результатом будет та же таблица.

Однако этот запрос:

SELECT Col1, Col2 FROM data GROUP BY Col1, Col2

Результат

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

Теперь запрос:

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

Создаст проблему: строка с A, Y является результатом группировки двух строк

 A     Y     2
 A     Y     3

Итак, какое значение должно быть в Col3, '2' или '3'?

Обычно вы должны использовать группу для вычисления, например. сумма:

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

Итак, в строке мы столкнулись с проблемой: теперь мы получаем (2 + 3) = 5.

Группировка всеми вашими столбцами в вашем элементе фактически аналогична использованию DISTINCT, и в этом случае предпочтительно использовать читабельность слова ключевого слова DISTINCT.

Итак, вместо

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

использование

SELECT DINSTINCT Col1, Col2, Col3 FROM data

Ответ 4

Единственный реальный случай использования GROUP BY без агрегации - это когда вы GROUP BY больше столбцов, чем выбрано, и в этом случае выбранные столбцы могут быть повторены. В противном случае вы можете использовать DISTINCT.

Стоит отметить, что в других СУБД не требуется включать все неагрегированные столбцы в GROUP BY. Например, в PostgreSQL, если столбцы первичного ключа в таблице включены в GROUP BY, тогда другие столбцы этой таблицы не должны быть такими, какими они гарантированы для каждого отдельного столбца первичного ключа. В прошлом я хотел, чтобы Oracle делала то же самое, что и во многих случаях для более компактного SQL.

Ответ 5

Позвольте мне привести несколько примеров.

Рассмотрим эти данные.

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;

Что там в таблице сейчас

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.

- совокупность с группой

SELECT
      VAL1,
      COUNT ( * )
FROM
      DATASET A
GROUP BY
      VAL1;

VAL1   COUNT(*)
---- ----------
b             1
a             2
c             2

3 rows selected.

- совокупность с группой по нескольким столбцам, но выберите частичный столбец

SELECT
      VAL1,
      COUNT ( * )
FROM
      DATASET A
GROUP BY
      VAL1,
      VAL2;

VAL1  
---- 
b             
c             
a             
a             

4 rows selected.

- нет агрегата с группой по нескольким столбцам

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.

- нет агрегата с группой по нескольким столбцам

SELECT
      VAL1
FROM
      DATASET A
GROUP BY
      VAL1,
      VAL2;

    VAL1  
    ---- 
    b
    c
    a
    a

    4 rows selected.

У вас есть N столбцов в select (исключая агрегации), тогда вы должны иметь столбцы N или N + x

Ответ 6

Если у вас есть столбец в предложении SELECT, как он будет выбирать его, если есть несколько строк? поэтому да, каждый столбец в предложении SELECT также должен быть в условии GROUP BY, вы можете использовать агрегатные функции в SELECT...

у вас может быть столбец в предложении GROUP BY, который не находится в предложении SELECT, но не иначе

Ответ 7

Использовать вспомогательный запрос, например:

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

ИЛИ

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

Ответ 8

Я знаю, что вы сказали, что хотите понять группу, если у вас есть такие данные:

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

И вы хотите, чтобы данные выглядели следующим образом:

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

Вы используете:

select * from table_name
order by col-c,colb

Потому что я думаю, что это то, что вы намереваетесь сделать.

Ответ 9

В качестве дополнения

в основном число столбцов должно быть равно числу столбцов в предложении GROUP BY

не является правильным утверждением.

  • Любой атрибут, который не является частью предложения GROUP BY, не может использоваться для выбора
  • Любой атрибут, являющийся частью предложения GROUP BY, может использоваться для выбора, но не обязательно.