Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Web программирование > SQL, базы данных
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 29.05.2012, 16:20   #1
daamail
 
Регистрация: 20.08.2008
Сообщений: 6
По умолчанию SQL поиск одинаковых ячеек и сумма стоящих рядом значений

Здравствуйте,
имеется таблица:

Дата | Клиент1 | Сумма1 | Клиент2 | Сумма2 | Клиент3 | Сумма3 |
01. Jan | A | 10 | A | 25 | B | 15 |
02. Jan | B | 20 | С | 10 | B | 10 |
03. Jan | A | 15 | B | 15 | A | 25 |

надо:
найти сумму по всем клиентам и по всем датам:
A | 75
B | 60
C | 10

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

который день уже бьюсь, но, к сожалению ничего на ум не приходит

спасибо!
daamail вне форума Ответить с цитированием
Старый 29.05.2012, 16:27   #2
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,238
По умолчанию

кто проектировал это безобразие?! Почему ТРИ записи собраны в ОДНУ запись?!!

я бы запросом вытягивал эти записи в линию, а потом уже группировал/суммировал.
примерно так:
Код:
select Client, sum(ClientSumma) from
  (select Дата, Клиент1 as Client, Сумма1 as ClientSumma
  union all
  select Дата, Клиент2 as Client, Сумма2 as ClientSumma
  union all
  select Дата, Клиент3 as Client, Сумма3 as ClientSumma )
group by Client
p.s. поле дата оставлено просто потому, что оно было в исходном запросе.
в данном случае оно никак не задействовано!
Serge_Bliznykov вне форума Ответить с цитированием
Старый 29.05.2012, 16:45   #3
daamail
 
Регистрация: 20.08.2008
Сообщений: 6
По умолчанию

Большое спасибо, буду пробовать.
Спроектировали вроде все путем, это - результат запроса из разных таблиц.
Просто данная инфа необходима для специфического анализа.

----

разобрался, все отлично.
спасибо

---------

а вот если усложнить запрос, интересно, решаемо ли это вообще:

-- добавляем столбец "лимит"

Дата | Лимит | Клиент1 | Сумма1 | Клиент2 | Сумма2 | Клиент3 | Сумма3 |
01. Jan | 40 | A | 10 | A | 25 | B | 15 |
02. Jan| 30 | B | 20 | С | 10 | B | 10 |
03. Jan | 35 | A | 15 | B | 15 | A | 25 |

это означает, что в один день, например 1 января, мы можем взять максимум 40 по всем клиентам, начиная с "Клиент1"
2 января макс. 30, и 3 января 35

необходимо получить следующее

A | 55
B | 40
C | 10

как считается:
например 1 января имеем лимит 40, поэтому берем А (10) + А (25) + В (5!!!)

спасибо!

Последний раз редактировалось daamail; 29.05.2012 в 17:56.
daamail вне форума Ответить с цитированием
Старый 05.06.2012, 16:06   #4
daamail
 
Регистрация: 20.08.2008
Сообщений: 6
По умолчанию

неужели никто не знает?
daamail вне форума Ответить с цитированием
Старый 06.06.2012, 09:56   #5
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,238
По умолчанию

задача не очень вписывается в реалиционную модель..

кроме того, а ответьте, плиз, что будет, например, для
Код:
Дата | Лимит | Клиент1 | Сумма1 | Клиент2 | Сумма2 | Клиент3 | Сумма3 |	
01. Jan | 40 | A | 50 | A | 25  | B | 15  |	
02. Jan | 30 | B | 20 | С | 100 | B | 10  |	
03. Jan | 35 | A | 20 | B | 10  | A | 100 |
???

и какая у Вас СУБД ?
Serge_Bliznykov вне форума Ответить с цитированием
Старый 06.06.2012, 15:11   #6
daamail
 
Регистрация: 20.08.2008
Сообщений: 6
По умолчанию

да, вот в этом и проблема, как-то надо это решить.

Ответ на ваш пример:

A: 40 (лимит1) + 20 (лимит3) + 5 (лимит3) = 65
B: 20 (лимит2) + 10 (лимит3) = 30
С: 10 (лимит 2) = 10


СУБД - Oracle


прошу прощения, если не точен в некоторых терминах.
я только учусь ...

а что если попробовать переделать данную таблицу с помощью WHEN,
т.е. по каждой строчке считаем: если 'Сумма1' меньше или равна 'Лимит1', то берем эту сумму и 'Клиент1', и т.д. до тех пор, пока суммы по сточке не будут больше 'Лимит1'. Если сумма будет больше, чем 'Лимит1', то в новую таблицу берем только часть суммы и 'Клинет'. Остальное в данной сточке нас больше не интересует.

т.е. привести вашу таблицу

Дата | Лимит | Клиент1 | Сумма1 | Клиент2 | Сумма2 | Клиент3 | Сумма3 |
01. Jan | 40 | A | 50 | A | 25 | B | 15 |
02. Jan | 30 | B | 20 | С | 100 | B | 10 |
03. Jan | 35 | A | 20 | B | 10 | A | 100 |

к следующему виду

Дата | Лимит | Клиент1 | Сумма1 | Клиент2 | Сумма2 | Клиент3 | Сумма3 |
01. Jan | 40 | A | 40 | |
02. Jan | 30 | B | 20 | С | 10 | |
03. Jan | 35 | A | 20 | B | 10 | A | 5 |

После этого вытягиваем все в линию и группируем (пост 2)

?

Последний раз редактировалось daamail; 06.06.2012 в 15:59.
daamail вне форума Ответить с цитированием
Старый 06.06.2012, 15:54   #7
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,238
По умолчанию

всё понятно с условием задачи.

я бы копал в сторону такого запроса (не проверял - это просто концепция - поправьте так, чтобы стало правильно):
Код:
select Client, sum(ClientSumma) from
  (select Дата, Клиент1 as Client, 
     case when Сумма1 < Limit then Сумма1 else Limit end as ClientSumma
  union all
  select Дата, Клиент2 as Client, 
     case when Сумма2  < (Limit-Сумма1) 
          then Сумма2 else greatest((Limit-Сумма1-Сумма2), 0) end  as  ClientSumma
  union all
  select Дата, Клиент3 as Client, 
     case when Сумма3  < (Limit-Сумма1-Сумма2) 
     then Сумма3 else greatest((Limit-Сумма1-Сумма2-Сумма3), 0) end as ClientSumma
)
group by Client
отлаживать запрос лучше так (только внутренняя часть запроса):
Код:
select Дата, Limit, Клиент1 as Client, 
     case when Сумма1 < Limit then Сумма1 else Limit end as ClientSumma
  union all
  select Дата, Limit, Клиент2 as Client, 
     case when Сумма2  < (Limit-Сумма1) 
          then Сумма2 else greatest((Limit-Сумма1-Сумма2), 0) end  as  ClientSumma
  union all
  select Дата, Limit, Клиент3 as Client, 
     case when Сумма3  < (Limit-Сумма1-Сумма2) 
     then Сумма3 else greatest((Limit-Сумма1-Сумма2-Сумма3), 0) end as ClientSumma
Serge_Bliznykov вне форума Ответить с цитированием
Старый 06.06.2012, 15:58   #8
daamail
 
Регистрация: 20.08.2008
Сообщений: 6
По умолчанию

спасибо, буду пробовать
daamail вне форума Ответить с цитированием
Старый 11.06.2012, 12:22   #9
daamail
 
Регистрация: 20.08.2008
Сообщений: 6
По умолчанию

не получается почему то
требует в 5 стоке скобку
ORA-00907: missing right parenthesis
00907. 00000 - "missing right parenthesis"

что я делаю не правильно?



Код:
select Client, sum(ClientSumma) 
from
  (
    select a.Дата,  a. Клиент1 as Client, 
       case when a. Сумма 1 < a. Limit then a. Сумма1 else a. Limit end as ClientSumma from test_ pv as a
    union all
    select a.Дата,  a. Клиент2 as Client, 
       case when a. Сумма2 < (a. Limit - a. Сумма1) 
            then a. Сумма2 else greatest((a. Limit- a. Сумма1- a. Сумма2), 0) end as ClientSumma from test_ pv as a
    union all
    select a.Дата,  a. Клиент3 as Client, 
       case when a. Сумма3 < (a. Limit- a. Сумма1- a. Сумма2) 
       then a. Сумма3 else greatest((a. Limit- a. Сумма1- a. Сумма2- a. Сумма3), 0) end as ClientSumma from test_ pv as a
  )
group by Client

Последний раз редактировалось Serge_Bliznykov; 11.06.2012 в 23:24.
daamail вне форума Ответить с цитированием
Старый 11.06.2012, 23:30   #10
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,238
По умолчанию

Цитата:
что я делаю не правильно?
да всё, что угодно.

для начала - откуда взялись пробелы после указания алиаса таблицы?!

потом, начните с малого.
такой запрос работает:
Код:
  select a.Дата,  a.Клиент1 as Client, 
       case when a.Сумма 1 < a.Limit then a.Сумма1 else a.Limit end as ClientSumma 
  from test_pv as a
если нет - разбирайтесь, почему (например, поля у Вас по другом называются. в таблице test_pv нет поля Сумма1 или поля Limit или поля Клиент1 и т.д.)

если работает.
тогда попробуйте чуть-чуть посложнее запрос.
такой, например:
Код:
select a.Дата,  a.Клиент3 as Client, 
       case 
       when a.Сумма3 < (a.Limit- a.Сумма1- a.Сумма2)
       then a.Сумма3 
       else greatest((a.Limit- a.Сумма1- a.Сумма2- a.Сумма3), 0) end as ClientSumma 
from test_pv as a

Вы же поймите, что я вам даю не готовый рецепт, а просто указывают направление, в какую сторону копать...

Последний раз редактировалось Serge_Bliznykov; 11.06.2012 в 23:33.
Serge_Bliznykov вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Форма вывода (вывод в два рядом стоящих столбца) Green Gin Общие вопросы C/C++ 2 09.12.2011 18:34
Задача, вывести пары одинаковых чисел стоящих рядом. Arn1 Помощь студентам 4 03.10.2011 11:39
Поиск одинаковых значений в столбце Батарейкина Microsoft Office Excel 4 21.02.2011 20:34
Алгоритм определения стоящих рядом одинаковых чисел, что не так. leshij Паскаль, Turbo Pascal, PascalABC.NET 2 12.02.2011 16:05
Задача о рядом стоящих симоволах. llTibegll Помощь студентам 2 07.11.2009 19:42