powered by simpleCommunicator - 2.0.59     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Informix [игнор отключен] [закрыт для гостей] / Помогите написать запрос, пожалуйста..
41 сообщений из 41, показаны все 2 страниц
Помогите написать запрос, пожалуйста..
    #34866318
Cold bringer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Есть таблица продаж, следующего вида:
Дата , Склад, Товар, Сумма

Нужно запросом получить Первые десять товаров, которые приняли наибольшее участие в выручке каждого дня - и так по каждому складу.

Первый сюприз для меня был в невозможности использование подзапросов в секции FROM. Второй - в невозможности использовать несколько MULTISET. Раньше лазил через ODBC-драйвер - особых проблем не возникало (понятно почему), теперь пытаюсь получить информацию через JDBC - и с "родными" запросами получается не так гладко. Пока вот что накрутил:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
SELECT t_from AS STORE, t_date AS MYDATE ,t_kod AS TOV,(SUM(t_sum))* 100 /mySUM AS PERC FROM 
S_TOTAL,TABLE(MULTISET(SELECT t_from AS myStore, t_date AS myDATE, Sum(t_sum) AS mySUM
FROM s_total
WHERE t_date BETWEEN  (TODAY -  31  UNITS DAY) AND (TODAY)
GROUP BY t_from, t_date))
WHERE t_from=myStore AND t_date=myDATE
GROUP BY t_from, t_date,t_kod,PERC 
ORDER BY PERC
Тут сервер мне говорит, что не найден столбец PERC и я решил попросить о помощи...
...
Рейтинг: 0 / 0
Помогите написать запрос, пожалуйста..
    #34867894
Артур.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Я бы для данного запроса написал бы хранимую процедурку... Не очень представляю как вы в рамках обычного sql будете выбирать первые 10 суммарных значений по каждому складу...
...
Рейтинг: 0 / 0
Помогите написать запрос, пожалуйста..
    #34867929
Бабичев Сергей
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Артур.Не очень представляю как вы в рамках обычного sql будете выбирать первые 10 суммарных значений по каждому складу...Написать-то такой запрос - не проблема. Порблема - просадка производительности, вызванная такого рода запросом
...
Рейтинг: 0 / 0
Помогите написать запрос, пожалуйста..
    #34868075
Cold bringer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Я не уверен - позволит ли INFORMIX корреляцию в MULTISET. Вот и обращаюсь за помощью.
...
Рейтинг: 0 / 0
Помогите написать запрос, пожалуйста..
    #34868206
Фотография Тан
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cold bringer
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
SELECT t_from AS STORE, t_date AS MYDATE ,t_kod AS TOV,
(SUM(t_sum))* 100 /mySUM AS PERC 
FROM S_TOTAL,
TABLE(MULTISET(SELECT t_from AS myStore, t_date AS myDATE, Sum(t_sum) AS mySUM
FROM s_total WHERE t_date BETWEEN  (TODAY -  31  UNITS DAY) AND (TODAY)
GROUP BY t_from, t_date))
WHERE t_from=myStore AND t_date=myDATE
GROUP BY t_from, t_date,t_kod,PERC 
ORDER BY PERC
Тут сервер мне говорит, что не найден столбец PERC и я решил попросить о помощи...
напишите
GROUP BY t_from, t_date,t_kod,4
ORDER BY 4
...
Рейтинг: 0 / 0
Помогите написать запрос, пожалуйста..
    #34868417
Cold bringer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Если пойти на компромисс, и задать постоянное количество складов, то можно попытаться обойтись банальным UNION-ом, но хочется же по уму.
...
Рейтинг: 0 / 0
Помогите написать запрос, пожалуйста..
    #34868629
Фотография Журавлев Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Это олап. Информикс не умеет олап, заваривать чай и бегать за пивом.
...
Рейтинг: 0 / 0
Помогите написать запрос, пожалуйста..
    #34868765
АнатоЛой
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не понял
Где
Код: plaintext
SELECT FIRST  10  ... 
?
...
Рейтинг: 0 / 0
Помогите написать запрос, пожалуйста..
    #34868820
Cold bringer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
2 Журавлев Денис
Да какой же это ОЛАП... Я не пробовал, но схема запроса, скажем, в ORACLE мне ясна.

2 АнатоЛой
Так не дошёл я до этого вообще.

В сервер INFORMIX-а влезать нельзя.
...
Рейтинг: 0 / 0
Помогите написать запрос, пожалуйста..
    #34868949
Cold bringer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Что-то совсем всё невесело.

Код: plaintext
GROUP BY t_from, t_date,t_kod, 4 
В GROUP BY нельзя использовать агрегирующую функцию

Код: plaintext
GROUP BY t_from, t_date,t_kod
Столбец perc должен быть включен в GROUP BY

Код: plaintext
GROUP BY t_from, t_date,t_kod,perc
Столбец perc не найден ни в одной из таблиц.

Что ж делать-то???
...
Рейтинг: 0 / 0
Помогите написать запрос, пожалуйста..
    #34869103
Фотография Тан
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cold bringerЧто-то совсем всё невесело.

Код: plaintext
GROUP BY t_from, t_date,t_kod, 4 
В GROUP BY нельзя использовать агрегирующую функцию

Код: plaintext
GROUP BY t_from, t_date,t_kod
Столбец perc должен быть включен в GROUP BY

Код: plaintext
GROUP BY t_from, t_date,t_kod,perc
Столбец perc не найден ни в одной из таблиц.

Что ж делать-то???
если б вы сделали тест, всем было бы легче вам помогать.
в GROUP BY должен быть включен на самом деле не весь столбец, а та составляющая, которая не является агрегатом - это поле mySUM

т.е. если вы напишите так:
Код: plaintext
1.
2.
SELECT t_from AS STORE, t_date AS MYDATE ,t_kod AS TOV, mySUM, (SUM(t_sum))* 100 /mySUM AS PERC
...
GROUP BY t_from, t_date,t_kod,mySUM
работать должно
...
Рейтинг: 0 / 0
Помогите написать запрос, пожалуйста..
    #34869129
Cold bringer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Как бы там не было - это лишь полумера - мне же нужно по всем складам за последние тридцать дней (за каждую дату). Если INFORMIX такого не может (одним запросом) - тады ой.
...
Рейтинг: 0 / 0
Помогите написать запрос, пожалуйста..
    #34869378
Cold bringer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Бабичев Сергей Артур.Не очень представляю как вы в рамках обычного sql будете выбирать первые 10 суммарных значений по каждому складу...Написать-то такой запрос - не проблема. Порблема - просадка производительности, вызванная такого рода запросом

Ну так подскажите, а?
...
Рейтинг: 0 / 0
Помогите написать запрос, пожалуйста..
    #34869547
Cold bringer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ладно, чёрт с ними, со складами - пропишу руками. Ну а хотя бы по датом такое можно нарисовать? Скажем - за десять последних..
...
Рейтинг: 0 / 0
Помогите написать запрос, пожалуйста..
    #34869856
OlegE
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вопрос, а что собственно мешает ХП написать?
...
Рейтинг: 0 / 0
Помогите написать запрос, пожалуйста..
    #34869898
Cold bringer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Сервер и вся информационная система находится на обслуживании. Когда мы просили предоставить возможность хотя бы просто читать инфу - было много охов и ахов. Если я вылезу с просьбами о хранимках и прочем - они начнут бросаться заявлениями "Снимаем с себя всю ответственность!". А на это никто не пойдет.
...
Рейтинг: 0 / 0
Помогите написать запрос, пожалуйста..
    #34870237
vasilis
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cold bringerКак бы там не было - это лишь полумера - мне же нужно по всем складам за последние тридцать дней (за каждую дату). Если INFORMIX такого не может (одним запросом) - тады ой.
А почему обязательно одним запросом ?
В Инфоримксе есть прекрасное средство - временные таблицы.
Сделайте сначала выборку туда, а затем выполняйте все необходимые операции.
Если данных много - можно даже индекс построить.
И работать будет быстрее с временной таблицей. И ухаживать за ними особо не надо.
...
Рейтинг: 0 / 0
Помогите написать запрос, пожалуйста..
    #34870314
Выбегалло
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cold bringerЕсть таблица продаж, следующего вида:
Дата , Склад, Товар, Сумма

Нужно запросом получить Первые десять товаров, которые приняли наибольшее участие в выручке каждого дня - и так по каждому складу.

Первый сюприз для меня был в невозможности использование подзапросов в секции FROM. Второй - в невозможности использовать несколько MULTISET. Раньше лазил через ODBC-драйвер - особых проблем не возникало (понятно почему), теперь пытаюсь получить информацию через JDBC - и с "родными" запросами получается не так гладко. Пока вот что накрутил:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
SELECT t_from AS STORE, t_date AS MYDATE ,t_kod AS TOV,(SUM(t_sum))* 100 /mySUM AS PERC FROM 
S_TOTAL,TABLE(MULTISET(SELECT t_from AS myStore, t_date AS myDATE, Sum(t_sum) AS mySUM
FROM s_total
WHERE t_date BETWEEN  (TODAY -  31  UNITS DAY) AND (TODAY)
GROUP BY t_from, t_date))
WHERE t_from=myStore AND t_date=myDATE
GROUP BY t_from, t_date,t_kod,PERC 
ORDER BY PERC
Тут сервер мне говорит, что не найден столбец PERC и я решил попросить о помощи...

1. create view mySUM as SELECT t_from AS myStore, t_date AS myDATE, t_kod AS TOV, Sum(t_sum) AS mySUM
FROM s_total
WHERE t_date BETWEEN (TODAY - 31 UNITS DAY) AND (TODAY)
GROUP BY t_from, t_date

2. select a.myStore, a.myDate, a.TOV, a.mySum
from mySum A
where
(select count(*) from mySum B where
a.myStore = b.myStore
and a.myDate = b.myDate
and a.mySum < b.mySum) < 10
...
Рейтинг: 0 / 0
Помогите написать запрос, пожалуйста..
    #34870319
Cold bringer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
2 Выбегалло

На самом деле - исходная таблица такова, что полностью соответсвует первому пункту.
Второй же мне пока не осилить - 10 минут уже медитирую. Осталось только попытаться, если сработает - просто нет слов.
...
Рейтинг: 0 / 0
Помогите написать запрос, пожалуйста..
    #34870320
Cold bringer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Понял. Но такого бы я не выдумал - это INFORMIX к такому толкает? ;)
...
Рейтинг: 0 / 0
Помогите написать запрос, пожалуйста..
    #34870494
Бабичев Сергей
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cold bringerНу так подскажите, а?
Вот тебе вариант реализации под Oracle, но с использованием конструкций, совместимых с ANSI SQL-92:
Код: plaintext
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.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
-- Подобие тестовых данных:
-- На эту часть запроса можно не обращать внимания
-- она нужна лишь для демонстрации того, 
-- на каких данных тестировался запрос.
with
  s_total as
  (
    select 'Склад №1' t_from, trunc(sysdate,'mm') +  0  t_date, 'Товар №1' t_kod,  10  t_sum from dual union all
    select 'Склад №1' t_from, trunc(sysdate,'mm') +  0  t_date, 'Товар №2' t_kod,  20  t_sum from dual union all
    select 'Склад №1' t_from, trunc(sysdate,'mm') +  0  t_date, 'Товар №3' t_kod,  30  t_sum from dual union all
    select 'Склад №1' t_from, trunc(sysdate,'mm') +  0  t_date, 'Товар №4' t_kod,  50  t_sum from dual union all
    select 'Склад №1' t_from, trunc(sysdate,'mm') +  0  t_date, 'Товар №5' t_kod,  50  t_sum from dual union all
--  
    select 'Склад №2' t_from, trunc(sysdate,'mm') +  0  t_date, 'Товар №1' t_kod,  50  t_sum from dual union all
    select 'Склад №2' t_from, trunc(sysdate,'mm') +  0  t_date, 'Товар №2' t_kod,  40  t_sum from dual union all
    select 'Склад №2' t_from, trunc(sysdate,'mm') +  0  t_date, 'Товар №3' t_kod,  30  t_sum from dual union all
    select 'Склад №2' t_from, trunc(sysdate,'mm') +  0  t_date, 'Товар №4' t_kod,  20  t_sum from dual union all
    select 'Склад №2' t_from, trunc(sysdate,'mm') +  0  t_date, 'Товар №5' t_kod,  10  t_sum from dual union all
-- --
    select 'Склад №1' t_from, trunc(sysdate,'mm') +  1  t_date, 'Товар №1' t_kod,  30  t_sum from dual union all
    select 'Склад №1' t_from, trunc(sysdate,'mm') +  1  t_date, 'Товар №2' t_kod,  20  t_sum from dual union all
    select 'Склад №1' t_from, trunc(sysdate,'mm') +  1  t_date, 'Товар №3' t_kod,  10  t_sum from dual union all
    select 'Склад №1' t_from, trunc(sysdate,'mm') +  1  t_date, 'Товар №4' t_kod,  40  t_sum from dual union all
    select 'Склад №1' t_from, trunc(sysdate,'mm') +  1  t_date, 'Товар №5' t_kod,  50  t_sum from dual union all
--
    select 'Склад №2' t_from, trunc(sysdate,'mm') +  1  t_date, 'Товар №1' t_kod,  50  t_sum from dual union all
    select 'Склад №2' t_from, trunc(sysdate,'mm') +  1  t_date, 'Товар №2' t_kod,  40  t_sum from dual union all
    select 'Склад №2' t_from, trunc(sysdate,'mm') +  1  t_date, 'Товар №3' t_kod,  10  t_sum from dual union all
    select 'Склад №2' t_from, trunc(sysdate,'mm') +  1  t_date, 'Товар №4' t_kod,  20  t_sum from dual union all
    select 'Склад №2' t_from, trunc(sysdate,'mm') +  1  t_date, 'Товар №5' t_kod,  30  t_sum from dual
  )
-- Конец тестовых данных.
--
-- Непосредственно сам запрос 
-- (используются исключительно стандартные возможности, 
-- описаные в ANSI SQL-92)
select v1.t_date, v1.t_from, v1.t_kod, v1.t_sum1, 
-- Ранжирование товара по суммарному вкладу в дневную выручку 
-- (от большего вклада к меньшему) в разрезе дня продажи и склада:
       count( 1 ) rnk 
  from (
         select t_date, t_from, t_kod, sum(t_sum) as t_sum1
           from s_total
          where t_date between sysdate -  31  and sysdate
          group by t_date, t_from, t_kod
       ) v1,
       (
         select t_date, t_from, t_kod, sum(t_sum) as t_sum1
           from s_total
          where t_date between sysdate -  31  and sysdate
          group by t_date, t_from, t_kod
       ) v2
 where v1.t_date = v2.t_date
   and v1.t_from = v2.t_from
   and (
         v1.t_sum1 < v2.t_sum1 
         or 
         v1.t_sum1 = v2.t_sum1 and v1.t_kod >= v2.t_kod
       )
 group by v1.t_date, v1.t_from, v1.t_kod, v1.t_sum1
having count( 1 ) <=  10 
 order by v1.t_date, v1.t_from, rnk

Query finished, retrieving results...

  T_DATE      T_FROM      T_KOD     T_SUM1   RNK
----------   --------    --------   ------   ---
 1 -окт- 2007    Склад № 1     Товар № 4         50       1  
 1 -окт- 2007    Склад № 1     Товар № 5         50       2  
 1 -окт- 2007    Склад № 1     Товар № 3         30       3  
 1 -окт- 2007    Склад № 1     Товар № 2         20       4  
 1 -окт- 2007    Склад № 1     Товар № 1         10       5  
 1 -окт- 2007    Склад № 2     Товар № 1         50       1  
 1 -окт- 2007    Склад № 2     Товар № 2         40       2  
 1 -окт- 2007    Склад № 2     Товар № 3         30       3  
 1 -окт- 2007    Склад № 2     Товар № 4         20       4  
 1 -окт- 2007    Склад № 2     Товар № 5         10       5  
 2 -окт- 2007    Склад № 1     Товар № 5         50       1  
 2 -окт- 2007    Склад № 1     Товар № 4         40       2  
 2 -окт- 2007    Склад № 1     Товар № 1         30       3  
 2 -окт- 2007    Склад № 1     Товар № 2         20       4  
 2 -окт- 2007    Склад № 1     Товар № 3         10       5  
 2 -окт- 2007    Склад № 2     Товар № 1         50       1  
 2 -окт- 2007    Склад № 2     Товар № 2         40       2  
 2 -окт- 2007    Склад № 2     Товар № 5         30       3  
 2 -окт- 2007    Склад № 2     Товар № 4         20       4  
 2 -окт- 2007    Склад № 2     Товар № 3         10       5  

 20  row(s) retrieved


Informix я в глаза не видел, но судя по краткому прочтению нескольких топиков, решение примет примерно такой вид (если ошибся где-то в синтаксисе, то пусть местные корифеи подправят меня):
Код: plaintext
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.
select v1.t_date, v1.t_from, v1.t_kod, v1.t_sum1, 
-- Ранжирование товара по суммарному вкладу в дневную выручку 
-- (от большего вклада к меньшему) в разрезе дня продажи и склада:
       count( 1 ) rnk
  from 
    table 
      (
        multiset
         (
           select t_date, t_from, t_kod, sum(t_sum) as t_sum1
             from s_total
            where t_date between (today -  31  units day) and (today)
            group by t_date, t_from, t_kod
         ) 
      ) v1,
    table 
      (
        multiset
         (
           select t_date, t_from, t_kod, sum(t_sum) as t_sum1
             from s_total
            where t_date between (today -  31  units day) and (today)
            group by t_date, t_from, t_kod
         ) 
      ) v2
 where v1.t_date = v2.t_date
   and v1.t_from = v2.t_from
   and (
         v1.t_sum1 < v2.t_sum1 
         or 
         v1.t_sum1 = v2.t_sum1 and v1.t_kod >= v2.t_kod
       )
 group by v1.t_date, v1.t_from, v1.t_kod, v1.t_sum1
having count( 1 ) <=  10 
 order by v1.t_date, v1.t_from, rnk

Но хочу предупредить, что данный запрос относится к так называемым slow-by-slow алгоритмам, скорость и объем работы которых оставляет желать лучшего...
...
Рейтинг: 0 / 0
Помогите написать запрос, пожалуйста..
    #34870875
Cold bringer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо, господа. Наверняка теперь к чему-нибудь приду. Хочу сказать, что "slow-by-slow" - это не то слово...
...
Рейтинг: 0 / 0
Помогите написать запрос, пожалуйста..
    #34871058
vasilis
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cold bringerПонял. Но такого бы я не выдумал - это INFORMIX к такому толкает? ;)
Когда не было всяких рюшечек типа "FIRST 10" то это был стандартный способ для выборки в стандартном запросе нужного количества строк (без использования процедуры). Хотя на самом деле, такое изящество нужно было крайне редко. У нас, например, много лет назад использовалось в одном из тестов по SQL, но так как почти никто не отвечал на этот вопрос, то пришлось его исключить.
...
Рейтинг: 0 / 0
Помогите написать запрос, пожалуйста..
    #34871098
Cold bringer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
2 Бабичев Сергей

Код: plaintext
and v1.t_kod >= v2.t_kod
А вот это зачем? Код вообще не числовой....
...
Рейтинг: 0 / 0
Помогите написать запрос, пожалуйста..
    #34871269
Бабичев Сергей
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cold bringer2 Бабичев Сергей

Код: plaintext
and v1.t_kod >= v2.t_kod
А вот это зачем? Код вообще не числовой....А это затем, чтобы нумератор вел себя как ROW_NUMBER() и раздавал товарам с одинаковой суммой продаж разные номера.
Про нечисловую природу кода - не понял. А что, в Informix-е строки сравнивать между собой нельзя?
...
Рейтинг: 0 / 0
Помогите написать запрос, пожалуйста..
    #34871338
vasilis
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Бабичев СергейА что, в Informix-е строки сравнивать между собой нельзя?
Конечно же можно.
...
Рейтинг: 0 / 0
Помогите написать запрос, пожалуйста..
    #34871736
zenk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А если несколько товаров дали в один день одну и ту же выручку?

Я не нашёл, где надо построить отчёт - в разрабатываемом приложении или в отчётной системе?
Если первое, то проблем с использованием временных таблиц быть не должно.
Если товаров сотни тысяч наименований, я бы написал примерно так:

Код: plaintext
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.
--Тут должны отловить ошибку "Таблица не существует"
DROP TABLE tmp_rank1;
CREATE TEMP TABLE tmp_rank1
          (t_from INT,
           t_date DATE,
           t_kod INT,
           t_sum DECIMAL( 13 , 2 ),
           my_rank SMALLINT)
WITH NO LOG;

INSERT INTO tmp_rank1
(SELECT DISTINCT t_from, t_date, t_kod, t_sum,  0 
 FROM s_total
 WHERE t_date BETWEEN (TODAY -  31  UNITS DAY) AND (TODAY));

CREATE INDEX tmp_rank1_i1 ON tmp_rank(t_from, t_date, t_sum);
UPDATE STATISTICS HIGH FOR TABLE tmp_rank1;

DROP TABLE tmp_rank2;
CREATE TEMP TABLE tmp_rank2
          (t_from INT,
           t_date DATE,
           t_sum DECIMAL( 13 , 2 ),
WITH NO LOG;

INSERT INTO tmp_rank2
(SELECT DISTINCT t_from, t_date, t_sum
  FROM tmp_rank1);

CREATE INDEX tmp_rank2_i1 ON tmp_rank2(t_from, t_date, t_sum);
UPDATE STATISTICS HIGH FOR TABLE tmp_rank2;

UPDATE tmp_rank1
SET Rank=(SELECT Count(*)
               FROM tmp_rank2
               WHERE tmp_rank1.t_from =  tmp_rank2.t_from
                   AND tmp_rank1.t_date = tmp_rank2.t_date
                   AND tmp_rank1.t_sum >=  tmp_rank2.t_sum);
               

Извините, если где-то ошибки в синтаксисе.
...
Рейтинг: 0 / 0
Помогите написать запрос, пожалуйста..
    #34871818
Cold bringer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Иэх, господа - это всё здорово, но такие запросы не возвращают результата. Запрос отсылается на сервер, в течении семидесяти минут не было ответа - потом я выключил. Обрабатывал пять дней, записей в таблице за этот период - 416 184.

Очень жаль.
...
Рейтинг: 0 / 0
Помогите написать запрос, пожалуйста..
    #34871831
zenk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
70 минут? Попробуйте мой запросик
...
Рейтинг: 0 / 0
Помогите написать запрос, пожалуйста..
    #34871944
Cold bringer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Я так понимаю, что конструкция

Код: plaintext
tmp_rank1.t_sum >=  tmp_rank2.t_sum)

в принципе нежизнеспособна. 400 000 строк, в квадрате - 16 и десять нулей (обрабатываемые строки) - а сервер не сдохнет, "как та корова"?
...
Рейтинг: 0 / 0
Помогите написать запрос, пожалуйста..
    #34871947
Cold bringer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Забавно, но накатать такой запрос с ручным обходом по складам и датам - будет НАСТОЛЬКО дешевле для сервера, что даже рядом не стояло.
...
Рейтинг: 0 / 0
Помогите написать запрос, пожалуйста..
    #34872719
Cold bringer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Угу, не стояло. Бдительный INFORMIX не даёт делать UNION и использовать FIRST в SELECT выражениях. Также не даёт использовать FIRST в table(multiset()). Я просто в шоке.

Я даже попытался сырые данные о продажах в ORACLE перетянуть, чтобы там уже обрабатывать, но это слишком долго тянется.

У меня подозрение, что для достижения искомой цели мне придётся забирать данные отдельными запросами, для каждого склада, и для каждой даты - в рамках одного коннекта - обалдеть.

Два дня уже убил.
...
Рейтинг: 0 / 0
Помогите написать запрос, пожалуйста..
    #34872956
Выбегалло
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cold bringerУгу, не стояло. Бдительный INFORMIX не даёт делать UNION и использовать FIRST в SELECT выражениях. Также не даёт использовать FIRST в table(multiset()). Я просто в шоке.

Я даже попытался сырые данные о продажах в ORACLE перетянуть, чтобы там уже обрабатывать, но это слишком долго тянется.

У меня подозрение, что для достижения искомой цели мне придётся забирать данные отдельными запросами, для каждого склада, и для каждой даты - в рамках одного коннекта - обалдеть.

Два дня уже убил.

Во-первых, не знаю какой у вас сервер, а у меня лаптоп вернул результаты для 400,000 записей за 10 минут :

---------
create table s_total (
t_from char(30),
t_date date,
t_kod int,
t_sum money(10,2)
);


create procedure ins_total (n int);
define i int;
define j int;
define k int;
define l int;

for i = 1 to n
LET l= mod(i, 20);
LET j = mod(i,30);
LET k = mod(i, 100);
insert into s_total values (l, today - j UNITS DAY, k, i);
end for;
end procedure;

call ins_total (400000)

create view mySUM (mystore, mydate, tov, mysum)
as
SELECT t_from,
t_date,
t_kod,
Sum(t_sum)
FROM s_total
WHERE t_date BETWEEN (TODAY - 31 UNITS DAY) AND (TODAY)
GROUP BY t_from, t_date, t_kod

--------- sel.sql ------
database dbase;
select a.myStore, a.myDate, a.TOV, a.mySum
from mySum A
where
(select count(*) from mySum B where
a.myStore = b.myStore
and a.myDate = b.myDate
and a.mySum < b.mySum) < 10
--------

/home/xxx>time dbaccess - sel.sql > /dev/null
Database selected.

300 row(s) retrieved.

Database closed.

real 10m22.572s
user 0m0.015s
sys 0m0.031s
-----------------

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

--------------- Variant 2 ------------
create temp table temp_t1 (
mystore char(30),
mydate date,
tov int,
mysum money(15,2)
);

create temp table temp_res (
mystore char(30),
mydate date,
tov int,
mysum money(15,2)
);

/* create a copy of summarized data */
insert into temp_t1
SELECT t_from as mystore,
t_date as mydate,
t_kod as tov,
Sum(t_sum) as mysum
FROM s_total
WHERE t_date BETWEEN (TODAY - 31 UNITS DAY) AND (TODAY)
GROUP BY t_from, t_date, t_kod;

/* find tovar with max mysum for each day, each store */
select mystore, mydate, max(mysum) mysum
from temp_t1
group by mystore, mydate
into temp temp_t3;


/* 1st place */
insert into temp_res
select a.mystore, a.mydate, a.tov, a.mysum
from temp_t1 a, temp_t3 b
where a.mystore= b.mystore
and a.mydate = b.mydate
and a.mysum = b.mysum;

delete from temp_t1
where exists (select 1 from temp_res
where temp_t1.mystore= temp_res.mystore
and temp_t1.mydate = temp_res.mydate
and temp_t1.mysum = temp_res.mysum);

/* 2nd place */
drop table temp_t3;

select mystore, mydate, max(mysum) mysum
from temp_t1
group by mystore, mydate
into temp temp_t3;

insert into temp_res
select a.mystore, a.mydate, a.tov, a.mysum
from temp_t1 a, temp_t3 b
where a.mystore= b.mystore
and a.mydate = b.mydate
and a.mysum = b.mysum;

delete from temp_t1
where exists (select 1 from temp_res
where temp_t1.mystore= temp_res.mystore
and temp_t1.mydate = temp_res.mydate
and temp_t1.mysum = temp_res.mysum);

/* 3rd place */
drop table temp_t3;

select mystore, mydate, max(mysum) mysum
from temp_t1
group by mystore, mydate
into temp temp_t3;

insert into temp_res
select a.mystore, a.mydate, a.tov, a.mysum
from temp_t1 a, temp_t3 b
where a.mystore= b.mystore
and a.mydate = b.mydate
and a.mysum = b.mysum;

delete from temp_t1
where exists (select 1 from temp_res
where temp_t1.mystore= temp_res.mystore
and temp_t1.mydate = temp_res.mydate
and temp_t1.mysum = temp_res.mysum);

/* 4 place */
drop table temp_t3;

select mystore, mydate, max(mysum) mysum
from temp_t1
group by mystore, mydate
into temp temp_t3;

insert into temp_res
select a.mystore, a.mydate, a.tov, a.mysum
from temp_t1 a, temp_t3 b
where a.mystore= b.mystore
and a.mydate = b.mydate
and a.mysum = b.mysum;

delete from temp_t1
where exists (select 1 from temp_res
where temp_t1.mystore= temp_res.mystore
and temp_t1.mydate = temp_res.mydate
and temp_t1.mysum = temp_res.mysum);

/* 5 place */
drop table temp_t3;

select mystore, mydate, max(mysum) mysum
from temp_t1
group by mystore, mydate
into temp temp_t3;

insert into temp_res
select a.mystore, a.mydate, a.tov, a.mysum
from temp_t1 a, temp_t3 b
where a.mystore= b.mystore
and a.mydate = b.mydate
and a.mysum = b.mysum;

delete from temp_t1
where exists (select 1 from temp_res
where temp_t1.mystore= temp_res.mystore
and temp_t1.mydate = temp_res.mydate
and temp_t1.mysum = temp_res.mysum);

/* 6 place */
drop table temp_t3;

select mystore, mydate, max(mysum) mysum
from temp_t1
group by mystore, mydate
into temp temp_t3;

insert into temp_res
select a.mystore, a.mydate, a.tov, a.mysum
from temp_t1 a, temp_t3 b
where a.mystore= b.mystore
and a.mydate = b.mydate
and a.mysum = b.mysum;

delete from temp_t1
where exists (select 1 from temp_res
where temp_t1.mystore= temp_res.mystore
and temp_t1.mydate = temp_res.mydate
and temp_t1.mysum = temp_res.mysum);

/* 7 place */
drop table temp_t3;

select mystore, mydate, max(mysum) mysum
from temp_t1
group by mystore, mydate
into temp temp_t3;

insert into temp_res
select a.mystore, a.mydate, a.tov, a.mysum
from temp_t1 a, temp_t3 b
where a.mystore= b.mystore
and a.mydate = b.mydate
and a.mysum = b.mysum;

delete from temp_t1
where exists (select 1 from temp_res
where temp_t1.mystore= temp_res.mystore
and temp_t1.mydate = temp_res.mydate
and temp_t1.mysum = temp_res.mysum);

/* 8 place */
drop table temp_t3;

select mystore, mydate, max(mysum) mysum
from temp_t1
group by mystore, mydate
into temp temp_t3;

insert into temp_res
select a.mystore, a.mydate, a.tov, a.mysum
from temp_t1 a, temp_t3 b
where a.mystore= b.mystore
and a.mydate = b.mydate
and a.mysum = b.mysum;

delete from temp_t1
where exists (select 1 from temp_res
where temp_t1.mystore= temp_res.mystore
and temp_t1.mydate = temp_res.mydate
and temp_t1.mysum = temp_res.mysum);

/* 9 place */
drop table temp_t3;

select mystore, mydate, max(mysum) mysum
from temp_t1
group by mystore, mydate
into temp temp_t3;

insert into temp_res
select a.mystore, a.mydate, a.tov, a.mysum
from temp_t1 a, temp_t3 b
where a.mystore= b.mystore
and a.mydate = b.mydate
and a.mysum = b.mysum;

delete from temp_t1
where exists (select 1 from temp_res
where temp_t1.mystore= temp_res.mystore
and temp_t1.mydate = temp_res.mydate
and temp_t1.mysum = temp_res.mysum);

/* 10 place */
drop table temp_t3;

select mystore, mydate, max(mysum) mysum
from temp_t1
group by mystore, mydate
into temp temp_t3;

insert into temp_res
select a.mystore, a.mydate, a.tov, a.mysum
from temp_t1 a, temp_t3 b
where a.mystore= b.mystore
and a.mydate = b.mydate
and a.mysum = b.mysum;

delete from temp_t1
where exists (select 1 from temp_res
where temp_t1.mystore= temp_res.mystore
and temp_t1.mydate = temp_res.mydate
and temp_t1.mysum = temp_res.mysum);

select * from temp_res;

----------
300 row(s) retrieved.


Database closed.


real 0m3.591s
user 0m0.031s
sys 0m0.015s

Инджой
...
Рейтинг: 0 / 0
Помогите написать запрос, пожалуйста..
    #34882043
vasilis
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Выбегалло
...
real 0m3.591s
user 0m0.031s
sys 0m0.015s
Инджой
Выбегалло, мои бурные аплодисменты (надеюсь, что и остальных тоже).
За потраченное время на написание кода и тестирование и за отстаивание чести Информикса, в которой некоторые несправедливо начали сомневаться :)
...
Рейтинг: 0 / 0
Помогите написать запрос, пожалуйста..
    #34882300
Cold bringer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
За потраченное время - огромная признательность, но отстаивание чести - вот этой простыней?
Мой сервер - это два XEON-а - почему-то 10 минут для него мало. Мой проект этим вот запросом не заканчивается, а я со страхом думаю о следующих задачах - там то что будет?

Смотрите, таблица:

Код: plaintext
USER_ID   NUMBER_OF_STATE  NAME_OF_STATE  START_OF_STATE

USERID - ID пользователя
NAMEOFSTATE - Название состояния пользователя (Перечисление,задано один раз, вида: "На рабочем месте","Отсутсвует","Отключен","Отсутсвует AUTO")
STARTOFSTATE - Начало состояния пользователя (Дата/время)
NUMBEROFSTATE - порядковый номер состояния, растёт в пределах юзера, строго +1 (можно было бы от этого столбца отказаться, но оставлен ради упрощения.)

Исходя из 8-ми часового рабочего дня - надо вывести таблицу вида:

Код: plaintext
1.
2.
Дата------На рабочем месте------Отсутствует-----Работа сверхнормы
   17 . 08 . 2007 -------7:30--------------------30---------------нет
   18 . 08 . 2007 ------- 8 : 22 --------------------Нет-------------- 22 
- и так - за весь требуемый период.

В ORACLE это один запрос. В INFORMIX-е наверное тоже можно понасоздавать таблиц, да вот только у моего пользователя нет на это прав. Только на SELECT.
...
Рейтинг: 0 / 0
Помогите написать запрос, пожалуйста..
    #34882932
Выбегалло
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cold bringerЗа потраченное время - огромная признательность, но отстаивание чести - вот этой простыней?
Мой сервер - это два XEON-а - почему-то 10 минут для него мало. Мой проект этим вот запросом не заканчивается, а я со страхом думаю о следующих задачах - там то что будет?

Смотрите, таблица:

Код: plaintext
USER_ID   NUMBER_OF_STATE  NAME_OF_STATE  START_OF_STATE

USERID - ID пользователя
NAMEOFSTATE - Название состояния пользователя (Перечисление,задано один раз, вида: "На рабочем месте","Отсутсвует","Отключен","Отсутсвует AUTO")
STARTOFSTATE - Начало состояния пользователя (Дата/время)
NUMBEROFSTATE - порядковый номер состояния, растёт в пределах юзера, строго +1 (можно было бы от этого столбца отказаться, но оставлен ради упрощения.)

Исходя из 8-ми часового рабочего дня - надо вывести таблицу вида:

Код: plaintext
1.
2.
Дата------На рабочем месте------Отсутствует-----Работа сверхнормы
   17 . 08 . 2007 -------7:30--------------------30---------------нет
   18 . 08 . 2007 ------- 8 : 22 --------------------Нет-------------- 22 
- и так - за весь требуемый период.

В ORACLE это один запрос. В INFORMIX-е наверное тоже можно понасоздавать таблиц, да вот только у моего пользователя нет на это прав. Только на SELECT.

Ну несите ваш оракловский запрос. Не исключено, что с минимальными переделками (или совсем без ) он будет работать на информиксе. Я бы вам нарисовал запрос, но непонятно что такое "отсуствует AUTO" и "отключен".
...
Рейтинг: 0 / 0
Помогите написать запрос, пожалуйста..
    #34882976
Cold bringer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В контексте условия - "отсуствует AUTO" и "отключен" эквивалентно "отсутвствует".

Но спорить я не буду, поскольку в вашем профессионализме не сомневаюсь.
...
Рейтинг: 0 / 0
Помогите написать запрос, пожалуйста..
    #34883763
Фотография Тан
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cold bringerЗа потраченное время - огромная признательность, но отстаивание чести - вот этой простыней?
...
В INFORMIX-е наверное тоже можно понасоздавать таблиц, да вот только у моего пользователя нет на это прав. Только на SELECT.
1. Не бывает в Informix пользователей, у которых нет права создавать временные таблицы.
2. Человек старался вам помочь, тратил время и силы, а вы даже не попробовали то, что он вам предложил.

ну подождите, может еще кто захочет помочь...
...
Рейтинг: 0 / 0
Помогите написать запрос, пожалуйста..
    #34883986
Cold bringer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Пф-ф-ф, вот только совестить меня не надо.

Такие простыни я могу накатать где угодно и на стороне какой угодно, РЕШЕНИЕМ это назвать можно с большой натяжкой.

Как вариант - поставить рядом с INFORMIX-ом в одной локалке ORACLE XE, и тянуть в него сырые данные, и обрабатывать уже в ORACLE. Я выбираю.
...
Рейтинг: 0 / 0
Помогите написать запрос, пожалуйста..
    #34886007
Выбегалло
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cold bringerПф-ф-ф, вот только совестить меня не надо.

Такие простыни я могу накатать где угодно и на стороне какой угодно, РЕШЕНИЕМ это назвать можно с большой натяжкой.

Как вариант - поставить рядом с INFORMIX-ом в одной локалке ORACLE XE, и тянуть в него сырые данные, и обрабатывать уже в ORACLE. Я выбираю.

Хочется лечить геморрой через рот, а гланды удалять через задницу - дело ваше.
...
Рейтинг: 0 / 0
Помогите написать запрос, пожалуйста..
    #34886035
Выбегалло
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кстати, проверил оригинальный запрос на втором лаптопе (тоже делл, но T7300) -

real 7m11.104s
user 0m0.031s
sys 0m0.000s


В таком вот аксепте
...
Рейтинг: 0 / 0
41 сообщений из 41, показаны все 2 страниц
Форумы / Informix [игнор отключен] [закрыт для гостей] / Помогите написать запрос, пожалуйста..
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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