Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Informix Новый топик    Ответить
 Толи косяк 12.10FC8, толи я переработал  [new]
falcon111
Member

Откуда:
Сообщений: 115
Добрый день.
Делаю расчет некоторой статистики и столкнулся со странным глюком.

В процедуре делается предрассчет и выборка данных, их подготовка и фильтрация, в конечном итоге по ним надо построить топ-клиентов по сумме продаж.

Делал так:
insert into tmp_StatisticsTopClientsSalesClientsTop(ClientId, Amount)
select first XTopX t1.ClientId, sum(t1.DstAmount)
from tmp_StatisticsTopClientsSalesPayments t1
group by 1
order by 2 desc;


Выходит полная лажа, там клиенты с одним-двумя платежами попадают в топ со смешными суммами.
Переделал так:
let i=0;
foreach select t1.ClientId, sum(t1.DstAmount)
        into    t_ClientId, t_Amount
        from tmp_StatisticsTopClientsSalesPayments t1
        group by 1
        order by 2 desc
  let i=i+1;
  if i>XTopX then exit foreach; end if;
  insert into tmp_StatisticsTopClientsSalesClientsTop(ClientId, Amount) values(t_ClientId, t_Amount);
end foreach;


Так все чудесно считает. Ощущение, что пора отдыхать, в трех соснах запутался уже, поясните почему результаты разные?
12 июл 17, 16:28    [20637712]     Ответить | Цитировать Сообщить модератору
 Re: Толи косяк 12.10FC8, толи я переработал  [new]
falcon111
Member

Откуда:
Сообщений: 115
Вот проверочный скрипт, повторяющий все типовые особенности вычисления - создание таблиц, индексов по ним, заполнение, редактирование, вычисление по таблицам без логирования в транзакции и пр.:
drop procedure if exists tmp_AggregationTest;
create procedure tmp_AggregationTest()
  define i, j integer;
  define v    money(20,2);

  begin
    on exception in (-206) -- table not found
      create temp table tmp_Test (
        SomeSer   serial,
        SomeId    integer,
        SomeValue money(20,2)
      ) with no log in TempSpace;
      create unique index tmp_Test_SomeSer on tmp_Test(SomeSer) in tempspace;
      create        index tmp_Test_SomeId  on tmp_Test(SomeId)  in tempspace;
      update statistics low for table tmp_Test;
    end exception with resume;
    delete from tmp_Test;
  end;

  begin work;
  for i=1 to 10000
    insert into tmp_Test(SomeId, SomeValue) values(1,1.01);
    insert into tmp_Test(SomeId, SomeValue) values(2,2.02);
    insert into tmp_Test(SomeId, SomeValue) values(3,3.03);
    insert into tmp_Test(SomeId, SomeValue) values(4,4.04);
    insert into tmp_Test(SomeId, SomeValue) values(5,5.05);
  end for;

  foreach select t.SomeSer
          into   i
          from tmp_Test t

    update tmp_Test as tt set tt.SomeValue=6+i/100-tt.SomeValue where tt.SomeSer=i;
  end foreach;

  begin
    on exception in (-206) -- table not found
      create temp table tmp_Test_Res1 (
        SomeId    integer,
        SomeValue money(20,2)
      ) with no log in TempSpace;
      update statistics low for table tmp_Test_Res1;
    end exception with resume;
    delete from tmp_Test_Res1;
  end;

  begin
    on exception in (-206) -- table not found
      create temp table tmp_Test_Res2 (
        SomeId    integer,
        SomeValue money(20,2)
      ) with no log in TempSpace;
      update statistics low for table tmp_Test_Res2;
    end exception with resume;
    delete from tmp_Test_Res2;
  end;

  insert into tmp_Test_Res1(SomeId, SomeValue)
  select first 3 t1.SomeId, sum(t1.SomeValue)
  from tmp_Test t1
  group by 1
  order by 2 desc;

  let j=0;
  foreach select t1.SomeId, sum(t1.SomeValue)
          into   i,         v
          from tmp_Test t1
          group by 1
          order by 2 desc

    let j=j+1;
    if j>3 then exit foreach; end if;
    insert into tmp_Test_Res2(SomeId, SomeValue) values(i,v);
  end foreach;

  commit work;

  return;
end procedure;
update statistics for procedure tmp_AggregationTest;

execute procedure tmp_AggregationTest();

select * from tmp_Test_Res1 order by 1;
select * from tmp_Test_Res2 order by 1;

drop procedure tmp_AggregationTest();


Результат работы:
someid      somevalue
---------------------------------
2                      2539750.00
3                      2529750.00
5                      2509750.00
3 rows selected.
someid      somevalue
---------------------------------
1                      2549750.00
2                      2539750.00
3                      2529750.00
3 rows selected.


Как видим, результаты разные. А должны быть одинаковыми. Баг?
12 июл 17, 17:54    [20638057]     Ответить | Цитировать Сообщить модератору
 Re: Толи косяк 12.10FC8, толи я переработал  [new]
яфшуеі
Guest
12.10FC6 - все одинаково
Недавно біл релиз FC9, посмотрите ошибки

индекс создавать лучше после заполнения таблиці, при создании индекса собирается и статистика (если не ошибаюсь, с 11.50 уже нет той проблемі которая біла ранее с временніми таблицами - необходимость обновлять статистику. достаточно только в правильном месте создать индекс)
14 июл 17, 10:06    [20643265]     Ответить | Цитировать Сообщить модератору
 Re: Толи косяк 12.10FC8, толи я переработал  [new]
falcon111
Member

Откуда:
Сообщений: 115
Проверил сегодня FC9. Точно так же. :(
26 июл 17, 21:42    [20678013]     Ответить | Цитировать Сообщить модератору
 Re: Толи косяк 12.10FC8, толи я переработал  [new]
falcon111
Member

Откуда:
Сообщений: 115
Кстати, если добавить update statistics low for table tmp_Test; перед foreach - тогда все пучком.
PS: А редактировать свои сообщения тут нельзя?
26 июл 17, 21:45    [20678018]     Ответить | Цитировать Сообщить модератору
Все форумы / Informix Ответить