powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Oracle 11 опция обязательной группировки по константам
7 сообщений из 7, страница 1 из 1
Oracle 11 опция обязательной группировки по константам
    #39812740
Jaffar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день.
Есть 2 сервера ORACLE.
Версия на обоих: Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit

Есть простой запрос:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
select t.Typ, count(t.ID) CNt,p.P1
from (select 'A' P1, 441 P2 from dual /**/ ) p
join(           select 1 ID, 'A' Typ from dual
     union all  select 2   , 'A' Typ from dual
     union all  select 3   , 'A' Typ from dual
     union all  select 4   , 'B' Typ from dual
     union all  select 5   , 'B' Typ from dual /**/ ) t on t.Typ = p.P1
group by t.Typ



На 1 сервере запрос выполняется без ошибок
На 2 сервере запрос с ошибкой " ORA-00979: not a GROUP BY expression " - ругается на поле p.P1 - т.к. его нет в предложении group by и оно не в агрегирующей функции.
Если же на 2 сервере в том же запросе поле p.P1 вставить в агрег. функцию и написать max(p.P1) - то все отрабатывает без ошибок.

Поскольку на этих серверах стоит одинаковая версия ORACLE - возникло предположение что такое поведение регулируется какой-то настройкой.
Вопрос какой и где?
...
Рейтинг: 0 / 0
Oracle 11 опция обязательной группировки по константам
    #39812743
Фотография -2-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Jaffar,

10053
...
Рейтинг: 0 / 0
Oracle 11 опция обязательной группировки по константам
    #39813233
Фотография SeaGate
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Jaffar,

Это Bug 5520732 Query with a missing GROUP BY item does not fail (no ORA-979) (ORA-00979 это корректное поведение)
Запрос нужно переписать. В текущем виде работать будет с _fix_control 5520732:off или optimizer_features_enable<11.2.0.1
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
TC@PDB>; select t.Typ, count(t.ID) CNt,p.P1
  2  from (select 'A' P1, 441 P2 from dual /**/ ) p
  3  join(           select 1 ID, 'A' Typ from dual
  4       union all  select 2   , 'A' Typ from dual
  5       union all  select 3   , 'A' Typ from dual
  6       union all  select 4   , 'B' Typ from dual
  7       union all  select 5   , 'B' Typ from dual /**/ ) t on t.Typ = p.P1
  8  group by t.Typ;
select t.Typ, count(t.ID) CNt,p.P1
                              *
ERROR at line 1:
ORA-00979: not a GROUP BY expression


TC@PDB>;
TC@PDB>; select /*+ opt_param('_fix_control' '5520732:0')*/t.Typ, count(t.ID) CNt,p.P1
  2  from (select 'A' P1, 441 P2 from dual /**/ ) p
  3  join(           select 1 ID, 'A' Typ from dual
  4       union all  select 2   , 'A' Typ from dual
  5       union all  select 3   , 'A' Typ from dual
  6       union all  select 4   , 'B' Typ from dual
  7       union all  select 5   , 'B' Typ from dual /**/ ) t on t.Typ = p.P1
  8  group by t.Typ;

T        CNT P
- ---------- -
A          3 A

TC@PDB>;
TC@PDB>; select /*+ optimizer_features_enable('11.1.0.7')*/t.Typ, count(t.ID) CNt,p.P1
  2  from (select 'A' P1, 441 P2 from dual /**/ ) p
  3  join(           select 1 ID, 'A' Typ from dual
  4       union all  select 2   , 'A' Typ from dual
  5       union all  select 3   , 'A' Typ from dual
  6       union all  select 4   , 'B' Typ from dual
  7       union all  select 5   , 'B' Typ from dual /**/ ) t on t.Typ = p.P1
  8  group by t.Typ;

T        CNT P
- ---------- -
A          3 A

...
Рейтинг: 0 / 0
Oracle 11 опция обязательной группировки по константам
    #39813246
Фотография -2-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SeaGateORA-00979 это корректное поведениеДля декларативного языка от перестановки мест групбаемых результат меняться не должен.
Дока явно разрешает константы без указания в group bysqlreferenceIf you also specify a group_by_clause in this statement, then this select list can contain only the following types of expressions:

Constants

Aggregate functions and the functions USER, UID, and SYSDATE

Expressions identical to those in the group_by_clause. If the group_by_clause is in a subquery, then all columns in the select list of the subquery must match the GROUP BY columns in the subquery. If the select list and GROUP BY columns of a top-level query or of a subquery do not match, then the statement results in ORA-00979.

Expressions involving the preceding expressions that evaluate to the same value for all rows in a group
...
Рейтинг: 0 / 0
Oracle 11 опция обязательной группировки по константам
    #39813259
Фотография SeaGate
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
-2-Для декларативного языка от перестановки мест групбаемых результат меняться не должен.
Если речь о "group by a, b" и "group by b, a", то конечно, но я не вижу какая перестановка имеется в виду в контексте исходного запроса.
-2-Дока явно разрешает константы без указания в group by

p.P1 не является constant value , это column.
SQL Language Reference говорит о том, что:
SQL Language ReferenceIf the select list and GROUP BY columns of a top-level query or of a subquery do not match, then the statement results in ORA-00979.
...
Рейтинг: 0 / 0
Oracle 11 опция обязательной группировки по константам
    #39813311
Фотография -2-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SeaGate-2-Для декларативного языка от перестановки мест групбаемых результат меняться не должен.Если речь о "group by a, b" и "group by b, a"Речь о месте декларации константы. От того, что она декларирована в подзапросе, не перестает быть константой. Но по факту может ора-979, а может и не может, как парсеру захочется переписать запрос:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
with t184 as (select 123 x, dummy from dual)
select x, count(*) from t184;

         X   COUNT(*)
---------- ----------
       123          1

with t184 as (select /*+ materialize */ 123 x, dummy from dual)
select x, count(*) from t184;

ORA-00937: not a single-group group function

with t184 as (select 123 x, dummy from dual)
select x, count(*) from t184 group by dummy;

ORA-00979: not a GROUP BY expression


SeaGate SQL Language Reference говорит о том, что:
SQL Language ReferenceIf the select list and GROUP BY columns of a top-level query or of a subquery do not match, then the statement results in ORA-00979. Columns of query это и константы, и любое выражение.
Употребление "top-level query or subquery" бессмысленно, вообще приписка про ошибку при нарушении только одного из пунктов перечеркивает все остальные. Корявость формулировки обусловлена поздними безграмотными правками предыдущей редакции. Раньше было тоже корявенько, но именно про subquery и про ошибку наборот:авторExpressions identical to those in the group_by_clause. If the group_by_clause is in a subquery, then the GROUP BY columns of the subquery must match the select list of the outer query. Any columns in the select list of the subquery that are not needed by the GROUP BY operation are ignored without error.
А еще раньше к фразе про идентичность приписок вообще не было.
...
Рейтинг: 0 / 0
Oracle 11 опция обязательной группировки по константам
    #39813781
Фотография SeaGate
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
-2-Речь о месте декларации константы. От того, что она декларирована в подзапросе, не перестает быть константой.
Такой запрос
Код: plsql
1.
select x, count(*) from (select 123 x from dual);


всегда должен завершаться с ошибкой по следующим причинам:
1. он зависит от того, как оптимизатор трансформирует запрос, выполняет ли merge inline view или нет (materialize заменен на документированный no_merge).
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
TC@PDB>; select x, count(*) from (select 123 x from dual);

         X   COUNT(*)
---------- ----------
       123          1

TC@PDB>; select /*+ no_merge(@inner)*/x, count(*) from (select /*+ qb_name(inner)*/123 x from dual);
select /*+ no_merge(@inner)*/x, count(*) from (select /*+ qb_name(inner)*/123 x from dual)
                             *
ERROR at line 1:
ORA-00937: not a single-group group function


Произошла агрессивная оптимизация.
Видится, что дешевле оптимизатору применить ряд трансформаций (simple view merging здесь),
потом запустить семантическую проверку на корректность использования агрегатной функции,
потом трансформировать дальше, чем запускать проверку на исходном запросе ("select x, count(*) from (select 123 x from dual)") и
затем на трансформированном ("select 123 x, count(*) from dual").

2. в текущей документации сказано, что он не должен работать (x есть в select list, однако не в GROUP BY columns):
If the select list and GROUP BY columns of a top-level query or of a subquery do not match, then the statement results in ORA-00979.


3. если попробовать притянуть определение "Constants" к "x", то это не получается, т.к. дока пишет про constants в "this select list":
If you also specify a group_by_clause in this statement, then this select list can contain only the following types of expressions:
Constants

В исходном примере "this select list" содержит некое поле "x" из inline view.
Это не constant, соответственно, пункт про constants к этому запросу не может быть применен.
Что не разрешено по доке, можно считать запрещенным.

По поводу старой документации:
старая документацияAny columns in the select list of the subquery that are not needed by the GROUP BY operation are ignored without error.

"not needed" без детализации допускает слишком широкую трактовку, которая, помимо прочего, может включать: "select x, count(*) from (select 123 x from dual)".
Текущая документация более строгая в этом плане, т.к. этого не содержит.

Например, есть Functional Dependency .
Конкретно, PostgreSQL позволяет поэтому вот такое:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
postgres@[local]:5432 mydb# create table fd(x int primary key, y int);
CREATE TABLE
Time: 5.473 ms
postgres@[local]:5432 mydb# select x, y from fd group by x;
 x | y
---+---
(0 rows)

Time: 0.858 ms


Что документировано здесь :
7.2.3. The GROUP BY and HAVING ClausesIf the products table is set up so that, say, product_id is the primary key, then it would be enough to group by product_id in the above example, since name and price would be functionally dependent on the product ID, and so there would be no ambiguity about which name and price value to return for each product ID group.

Однако я не видел, чтобы Oracle когда-то это поддерживал, хотя "y" "not needed" (x уже primary key).
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
TC@PDB>; create table fd(x int primary key, y int);

Table created.

TC@PDB>; select x, y from fd group by x;
select x, y from fd group by x
          *
ERROR at line 1:
ORA-00979: not a GROUP BY expression


Т.о. правильно сделали, что удалили это предложение из документации.
...
Рейтинг: 0 / 0
7 сообщений из 7, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Oracle 11 опция обязательной группировки по константам
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]