AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск Все разделы прочитаны

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 12.10.2009, 20:23   #1  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,440 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Group by и временная таблица
AX 4.0 SP2

Тестируя отчёт, случайно поймал глюк:
X++:
static void job(Args _args)
{
    tmpTable tmpTable;
    counter cnt;
    ;

    tmpTable.clear();
    tmpTable.Field1 = '1';
    tmpTable.insert();

    tmpTable.clear();
    tmpTable.Field1 = '1';
    tmpTable.insert(); // вставляем две одинаковые строки

    cnt = 0;
    while select tmpTable
    group by Field1
//    where tmpTable.Field1 == '1'
    {
        cnt++;
    }

    info(int2str(cnt));
}
Если раскомментировать предложение WHERE то цикл выполнится 2 раза! У кого-нибудь воспроизводится?

P.S.: Обязательные условия: таблица - временная; поле - текстовое
За это сообщение автора поблагодарили: miklenew (3).
Старый 12.10.2009, 20:36   #2  
Varmen is offline
Varmen
Участник
 
190 / 13 (1) ++
Регистрация: 02.10.2007
а это не потому что,
select TmpTable = select * from TmpTable, т.е со всей тучей полей типа RecId itd?

Группировка соответсвенно тут не помогает.


Т.е нужно явно написать

X++:
select Field1 from tmpTable
group by Field1
__________________
The Variable men power.

Последний раз редактировалось Varmen; 12.10.2009 в 20:44.
Старый 12.10.2009, 20:47   #3  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,440 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Не помогает . И к тому же без where - работает корректно!
Старый 12.10.2009, 21:21   #4  
ZVV is offline
ZVV
MCITP
MCP
Oracle
MCBMSS
 
1,006 / 246 (11) ++++++
Регистрация: 13.02.2004
Адрес: Минск
->
Цитата:
Сообщение от Varmen Посмотреть сообщение
а это не потому что,
select TmpTable = select * from TmpTable, т.е со всей тучей полей типа RecId itd?

Группировка соответсвенно тут не помогает.


Т.е нужно явно написать

X++:
select Field1 from tmpTable
group by Field1
Нужели вы каждый раз так пишете при группировке?
Аксапта сама этот момент "распознаёт", так что явно писать вовсе не обязательно.
__________________
Zhirenkov Vitaly
Старый 12.10.2009, 21:57   #5  
Varmen is offline
Varmen
Участник
 
190 / 13 (1) ++
Регистрация: 02.10.2007
ага, особенно когда join , не раз палился. при поиске ошибки, лучше явно поставить, дабы исключить разную трактовку ситуации.
__________________
The Variable men power.

Последний раз редактировалось Varmen; 12.10.2009 в 22:02.
Старый 12.10.2009, 22:06   #6  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,440 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от Varmen Посмотреть сообщение
ага, особенно когда join , не раз палился. при поиске ошибки, лучше явно поставить, дабы исключить разную трактовку ситуации.
А пример можете привести, когда явное указания выбираемых полей, участвующих в группировке, хоть как-то влияет на результат?

Цитата:
Сообщение от ZVV Посмотреть сообщение
Аксапта сама этот момент "распознаёт", так что явно писать вовсе не обязательно.
+1
Старый 12.10.2009, 22:28   #7  
Varmen is offline
Varmen
Участник
 
190 / 13 (1) ++
Регистрация: 02.10.2007
не, не смогу такое привести.
Но ведь Вы мною предложенный вариант попробовали правда? Знаете почему, потому что jobik не работает так как изначально задумали, а причина неизвестна.
__________________
The Variable men power.
Старый 12.10.2009, 22:55   #8  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,440 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
не работает "как задумали" - мягко сказано

Если фильтровать текстовое поле, участвующее в группировке, то group by попросту игнорируется! (причём, например, для целочисленного поля тот же код отрабатывает корректно )

Что я делаю не так?
Кто-нибудь может прокомментрировать такое поведение group by? Это следствие каких-то известных (документированных) ограничений?
И какие ещё сюрпризы от использования временных таблиц можно ожидать?
Старый 12.10.2009, 23:21   #9  
Varmen is offline
Varmen
Участник
 
190 / 13 (1) ++
Регистрация: 02.10.2007
могу подвердить, зашел на нашу систему, также исполняется два раза.
Ах4.0сп2
__________________
The Variable men power.
Старый 12.10.2009, 23:24   #10  
Varmen is offline
Varmen
Участник
 
190 / 13 (1) ++
Регистрация: 02.10.2007
баг можно побороть, если вставить не явно поле, как я предпологал выше, а функцию агрегации над ним. Тогда аксапта "распознает" что таки надо группировать!

X++:
  while select maxof(Field1) from  t
  group by Field1
   where t.Field1 == '1'
   {
    info(strfmt("fisrt query %1",t.Field1));
   }
__________________
The Variable men power.

Последний раз редактировалось Varmen; 12.10.2009 в 23:34.
За это сообщение автора поблагодарили: S.Kuskov (1).
Старый 12.10.2009, 23:29   #11  
Varmen is offline
Varmen
Участник
 
190 / 13 (1) ++
Регистрация: 02.10.2007
X++:
static void Job10(Args _args)
{
 TempDummyTable t;
 ;
ttsbegin;
   t.Field1="1";
   t.insert();
ttscommit;
ttsbegin;
   t.Field1="1";
   t.insert();
ttscommit;
 
   
   while select maxof(Field1) from  t
  group by Field1
   where t.Field1 == '1'
   {
    info(strfmt("fisrt query %1",t.Field1));
   }
 
    while select t
  group by Field1
  where t.Field1 == '1'
   {
    info(strfmt("second query %1",t.Field1));
   }
}
Сообщение (21:28:38)
fisrt query 1
second query 1
second query 1
__________________
The Variable men power.
Старый 12.10.2009, 23:39   #12  
Varmen is offline
Varmen
Участник
 
190 / 13 (1) ++
Регистрация: 02.10.2007
Ну что смеемся дальше?
добавим поле Фиелд2
X++:
static void Job10(Args _args)
{
 TempDummyTable t;
 ;
ttsbegin;
   t.Field1="1";
   t.Field2="2";
   t.insert();
ttscommit;
ttsbegin;
   t.Field1="1";
   t.Field2="4";
   t.insert();
ttscommit;
 
   
   while select maxof(Field1) from  t
  group by Field1
   where t.Field1 == '1'
   {
    info(strfmt("fisrt query %1--%2",t.Field1,t.Field2));
   }
 
    while select t
  group by Field1
  where t.Field1 == '1'
   {
    info(strfmt("second query %1--%2",t.Field1,t.Field2));
   }
}
Сообщение (21:37:37)
fisrt query 1--
second query 1--2
second query 1--4

Ну куда группировка делась, во втором случае?
__________________
The Variable men power.
Старый 12.10.2009, 23:45   #13  
Varmen is offline
Varmen
Участник
 
190 / 13 (1) ++
Регистрация: 02.10.2007
ну и под занавес, мой любимый RecId itd
X++:
static void Job10(Args _args)
{
 TempDummyTable t;
 ;
ttsbegin;
   t.Field1="1";
   t.Field2="2";
   t.insert();
ttscommit;
ttsbegin;
   t.Field1="1";
   t.Field2="4";
   t.insert();
ttscommit;
 
 
   while select maxof(Field1) from  t
  group by Field1
   where t.Field1 == '1'
   {
    info(strfmt("fisrt query %1--%2",t.Field1,t.Field2));
   }
 
    while select t
  group by Field1
  where t.Field1 == '1'
   {
    info(strfmt("second query %1--%2--%3",t.Field1,t.Field2,t.RecId));
   }
}
 
 (21:44:51)
fisrt query 1--
second query 1--2--1328
second query 1--4--1376
__________________
The Variable men power.
Старый 13.10.2009, 00:13   #14  
ZVV is offline
ZVV
MCITP
MCP
Oracle
MCBMSS
 
1,006 / 246 (11) ++++++
Регистрация: 13.02.2004
Адрес: Минск
->
Цитата:
Сообщение от Varmen Посмотреть сообщение
....
Ну куда группировка делась, во втором случае?
Вы имеете ввиду, что результаты никак не сгруппировались вобще и в остальных колонках тоже есть данные? Ну мне кажется это сразу было очевидно, что Аксапта "забыла" сделать груп_бай вообще. Например можно было попробовать вставить не 2, а 3 или 4 строки.

По сути... Проверил на DAX2009 SP1 - результат абсолютно тот же. Реальный баг. Видимо разработчики такой вырожденный случай тупо забыли/не подумали закодить. ))
Почему "вырожденный"? Ну потому что вы по сути хотите выяснить есть ли у вас хоть одна строка со значением "1". С точки зрения производительности и логики я думаю лучше было бы написать этот запрос примерно так:
X++:
    while select firstFast firstOnly Field1 from tmpTable
    where tmpTable.Field1 == '1'
, чем гонять зря группировку...
Так работает...
__________________
Zhirenkov Vitaly
Старый 13.10.2009, 00:56   #15  
DSPIC is offline
DSPIC
Боец
 
1,077 / 1243 (44) ++++++++
Регистрация: 11.04.2008
Цитата:
Сообщение от ZVV Посмотреть сообщение
Вы имеете ввиду, что результаты никак не сгруппировались вобще и в остальных колонках тоже есть данные? Ну мне кажется это сразу было очевидно, что Аксапта "забыла" сделать груп_бай вообще. Например можно было попробовать вставить не 2, а 3 или 4 строки.

По сути... Проверил на DAX2009 SP1 - результат абсолютно тот же. Реальный баг. Видимо разработчики такой вырожденный случай тупо забыли/не подумали закодить. ))
Почему "вырожденный"? Ну потому что вы по сути хотите выяснить есть ли у вас хоть одна строка со значением "1". С точки зрения производительности и логики я думаю лучше было бы написать этот запрос примерно так:
X++:
    while select firstFast firstOnly Field1 from tmpTable
    where tmpTable.Field1 == '1'
, чем гонять зря группировку...
Так работает...
Не совсем согласен с вырожденностью. Я, например, хочу получить итоговые суммы по отделам, наименования которых начинаются на "OUT*"

X++:
 while select sum (amount) from tmpTable
    group by department
      where tmpTable.department like 'OUT*'
    {
        info(strFmt("%1 - %2", tmpTable.department, tmpTable.amount));
    }
(не знаю, правда, как like поведет себя в данном случае, но не суть)
Старый 13.10.2009, 01:09   #16  
Varmen is offline
Varmen
Участник
 
190 / 13 (1) ++
Регистрация: 02.10.2007
или скажем узнать кол-во уволенных сотрудников в связи с кризисом по отделам, имеющим признак ="CLOSED"
__________________
The Variable men power.

Последний раз редактировалось Varmen; 13.10.2009 в 01:17.
Старый 13.10.2009, 08:41   #17  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,440 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от Varmen Посмотреть сообщение
узнать кол-во уволенных сотрудников в связи с кризисом по отделам, имеющим признак ="CLOSED"
Можно. Вы же сами предложили выход
Цитата:
Сообщение от Varmen Посмотреть сообщение
баг можно побороть, если вставить не явно поле, как я предпологал выше, а функцию агрегации над ним. Тогда аксапта "распознает" что таки надо группировать!
Т.е. такая конструкция всётаки работает
X++:
  while select maxof(Field1), count(RecId) from  t
  group by Field1
   where t.Field1 == '1'
   {
    info(strfmt("fisrt query %1 %2",t.Field1, t.RecId));
   }

Последний раз редактировалось S.Kuskov; 13.10.2009 в 08:59. Причина: поспешил с выводами
Старый 13.10.2009, 09:03   #18  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,440 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от DSPIC Посмотреть сообщение
Не совсем согласен с вырожденностью. Я, например, хочу получить итоговые суммы по отделам, наименования которых начинаются на "OUT*" (не знаю, правда, как like поведет себя в данном случае)
С like всё теже самые проблемы


А по поводу вырожденности случая - не всегда удобно обробатывать его отдельно. Например, я часто использую в условии запроса такую конструкцию
X++:
((prmValue == "") || (Table.Field1 == prmValue))
Т.е. если пользователь не хочет ограничивать запрос, то он оставляет параметр пустым, иначе должна выбраться только одна группа. Или даже так
X++:
((prmValue == "") || (Table.Field1 like prmValue))


P.S.: Вот сижу сейчас и думаю, как же я раньше на такие грабли не наступал? Может действительно пример искуственен, а в жизни есть какая-то комбинация дополнительных условий, которая всегда спасала?

Последний раз редактировалось S.Kuskov; 13.10.2009 в 09:10.
Старый 13.10.2009, 10:44   #19  
ZVV is offline
ZVV
MCITP
MCP
Oracle
MCBMSS
 
1,006 / 246 (11) ++++++
Регистрация: 13.02.2004
Адрес: Минск
->
Цитата:
Сообщение от DSPIC Посмотреть сообщение
Не совсем согласен с вырожденностью. Я, например, хочу получить итоговые суммы по отделам, наименования которых начинаются на "OUT*"

X++:
 while select sum (amount) from tmpTable
    group by department
      where tmpTable.department like 'OUT*'
    {
        info(strFmt("%1 - %2", tmpTable.department, tmpTable.amount));
    }
(не знаю, правда, как like поведет себя в данном случае, но не суть)
Говоря о вырожденном случае, я имел ввиду случай из примера:
X++:
   while select tmpTable
    group by Field1
    where tmpTable.Field1 == '1'
, где "вы по сути хотите выяснить есть ли у вас хоть одна строка со значением "1"". Приведённый вами пример - это совсем другой, не вырожденный случай, и выше было показано, что при наличии агрегирующих функций в запросе баг не воспроизводится...
К чему придираемся?
__________________
Zhirenkov Vitaly
За это сообщение автора поблагодарили: DSPIC (0).
Старый 13.10.2009, 13:40   #20  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,440 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от Lemming Посмотреть сообщение
p.s. Знатный оффтопик получился
Предлагаю вынести сообщения #19, 20, 22-31 в отдельную тему "Временным таблицам фиолетово на транзакции"


--- Модератор: оффтопик перенесен в Временные таблицы и транзакции ---

Последний раз редактировалось Dron AKA andy; 13.10.2009 в 14:26.
Теги
bug, баг, временная таблица, запрос (query), ошибка

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Временная таблица Antoncheg DAX: Программирование 21 15.08.2008 18:25
производительность: map или временная таблица kitty DAX: Программирование 5 15.11.2007 12:36
Временная таблица + RLS leshy DAX: Программирование 6 27.04.2006 12:39
select sum(amount) from временная таблица ATimTim DAX: Программирование 6 11.06.2004 14:16
next и временная таблица Dron AKA andy DAX: Программирование 3 24.04.2003 16:42
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 01:18.