Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Informix [игнор отключен] [закрыт для гостей] / Помогите написать запрос, пожалуйста.. / 25 сообщений из 41, страница 1 из 2
12.10.2007, 21:44
    #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
15.10.2007, 09:13
    #34867894
Артур.
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите написать запрос, пожалуйста..
Я бы для данного запроса написал бы хранимую процедурку... Не очень представляю как вы в рамках обычного sql будете выбирать первые 10 суммарных значений по каждому складу...
...
Рейтинг: 0 / 0
15.10.2007, 09:33
    #34867929
Бабичев Сергей
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите написать запрос, пожалуйста..
Артур.Не очень представляю как вы в рамках обычного sql будете выбирать первые 10 суммарных значений по каждому складу...Написать-то такой запрос - не проблема. Порблема - просадка производительности, вызванная такого рода запросом
...
Рейтинг: 0 / 0
15.10.2007, 10:32
    #34868075
Cold bringer
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите написать запрос, пожалуйста..
Я не уверен - позволит ли INFORMIX корреляцию в MULTISET. Вот и обращаюсь за помощью.
...
Рейтинг: 0 / 0
15.10.2007, 11:06
    #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
15.10.2007, 11:55
    #34868417
Cold bringer
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите написать запрос, пожалуйста..
Если пойти на компромисс, и задать постоянное количество складов, то можно попытаться обойтись банальным UNION-ом, но хочется же по уму.
...
Рейтинг: 0 / 0
15.10.2007, 12:40
    #34868629
Журавлев Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите написать запрос, пожалуйста..
Это олап. Информикс не умеет олап, заваривать чай и бегать за пивом.
...
Рейтинг: 0 / 0
15.10.2007, 13:10
    #34868765
АнатоЛой
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите написать запрос, пожалуйста..
Не понял
Где
Код: plaintext
SELECT FIRST  10  ... 
?
...
Рейтинг: 0 / 0
15.10.2007, 13:24
    #34868820
Cold bringer
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите написать запрос, пожалуйста..
2 Журавлев Денис
Да какой же это ОЛАП... Я не пробовал, но схема запроса, скажем, в ORACLE мне ясна.

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

В сервер INFORMIX-а влезать нельзя.
...
Рейтинг: 0 / 0
15.10.2007, 13:51
    #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
15.10.2007, 14:36
    #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
15.10.2007, 14:42
    #34869129
Cold bringer
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите написать запрос, пожалуйста..
Как бы там не было - это лишь полумера - мне же нужно по всем складам за последние тридцать дней (за каждую дату). Если INFORMIX такого не может (одним запросом) - тады ой.
...
Рейтинг: 0 / 0
15.10.2007, 15:44
    #34869378
Cold bringer
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите написать запрос, пожалуйста..
Бабичев Сергей Артур.Не очень представляю как вы в рамках обычного sql будете выбирать первые 10 суммарных значений по каждому складу...Написать-то такой запрос - не проблема. Порблема - просадка производительности, вызванная такого рода запросом

Ну так подскажите, а?
...
Рейтинг: 0 / 0
15.10.2007, 16:21
    #34869547
Cold bringer
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите написать запрос, пожалуйста..
Ладно, чёрт с ними, со складами - пропишу руками. Ну а хотя бы по датом такое можно нарисовать? Скажем - за десять последних..
...
Рейтинг: 0 / 0
15.10.2007, 17:41
    #34869856
OlegE
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите написать запрос, пожалуйста..
Вопрос, а что собственно мешает ХП написать?
...
Рейтинг: 0 / 0
15.10.2007, 17:53
    #34869898
Cold bringer
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите написать запрос, пожалуйста..
Сервер и вся информационная система находится на обслуживании. Когда мы просили предоставить возможность хотя бы просто читать инфу - было много охов и ахов. Если я вылезу с просьбами о хранимках и прочем - они начнут бросаться заявлениями "Снимаем с себя всю ответственность!". А на это никто не пойдет.
...
Рейтинг: 0 / 0
15.10.2007, 20:41
    #34870237
vasilis
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите написать запрос, пожалуйста..
Cold bringerКак бы там не было - это лишь полумера - мне же нужно по всем складам за последние тридцать дней (за каждую дату). Если INFORMIX такого не может (одним запросом) - тады ой.
А почему обязательно одним запросом ?
В Инфоримксе есть прекрасное средство - временные таблицы.
Сделайте сначала выборку туда, а затем выполняйте все необходимые операции.
Если данных много - можно даже индекс построить.
И работать будет быстрее с временной таблицей. И ухаживать за ними особо не надо.
...
Рейтинг: 0 / 0
15.10.2007, 22:07
    #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
15.10.2007, 22:21
    #34870319
Cold bringer
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите написать запрос, пожалуйста..
2 Выбегалло

На самом деле - исходная таблица такова, что полностью соответсвует первому пункту.
Второй же мне пока не осилить - 10 минут уже медитирую. Осталось только попытаться, если сработает - просто нет слов.
...
Рейтинг: 0 / 0
15.10.2007, 22:24
    #34870320
Cold bringer
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите написать запрос, пожалуйста..
Понял. Но такого бы я не выдумал - это INFORMIX к такому толкает? ;)
...
Рейтинг: 0 / 0
16.10.2007, 07:01
    #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
16.10.2007, 11:03
    #34870875
Cold bringer
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите написать запрос, пожалуйста..
Спасибо, господа. Наверняка теперь к чему-нибудь приду. Хочу сказать, что "slow-by-slow" - это не то слово...
...
Рейтинг: 0 / 0
16.10.2007, 11:54
    #34871058
vasilis
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите написать запрос, пожалуйста..
Cold bringerПонял. Но такого бы я не выдумал - это INFORMIX к такому толкает? ;)
Когда не было всяких рюшечек типа "FIRST 10" то это был стандартный способ для выборки в стандартном запросе нужного количества строк (без использования процедуры). Хотя на самом деле, такое изящество нужно было крайне редко. У нас, например, много лет назад использовалось в одном из тестов по SQL, но так как почти никто не отвечал на этот вопрос, то пришлось его исключить.
...
Рейтинг: 0 / 0
16.10.2007, 12:04
    #34871098
Cold bringer
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите написать запрос, пожалуйста..
2 Бабичев Сергей

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

Код: plaintext
and v1.t_kod >= v2.t_kod
А вот это зачем? Код вообще не числовой....А это затем, чтобы нумератор вел себя как ROW_NUMBER() и раздавал товарам с одинаковой суммой продаж разные номера.
Про нечисловую природу кода - не понял. А что, в Informix-е строки сравнивать между собой нельзя?
...
Рейтинг: 0 / 0
Форумы / Informix [игнор отключен] [закрыт для гостей] / Помогите написать запрос, пожалуйста.. / 25 сообщений из 41, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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