+7 (495) 229-0436   shopadmin@itshop.ru 119334, г. Москва, ул. Бардина, д. 4, корп. 3
 
 
Вход
 
 
Каталог
 
 
Подписка на новости
Новости ITShop
Windows 7 и Office: Новости и советы
Обучение и сертификация Microsoft
Вопросы и ответы по MSSQLServer
Delphi - проблемы и решения
Adobe Photoshop: алхимия дизайна
 
Ваш отзыв
Оцените качество магазина ITShop.ru на Яндекс.Маркете. Если вам нравится наш магазин - скажите об этом Google!
 
 
Способы оплаты
 
Курс расчета
 
 1 у.е. = 91.78 руб.
 
 Цены показывать:
 
 
 
 
  
Новости, статьи, акции
 

Снова аналитические функции

24.03.2010 11:46

Балансировка нагрузки на сотрудников - снова аналитические функции

Том,

У меня возникла следующая проблема с оператором update:

Есть таблица кредитов (loan):

state_cd,
user_id,
status_cd,
...

И таблица user_state_served:

user_id,
state_cd,
last_asgnmt_dt

Хотелось бы распределить кредиты равномерно среди сотрудников, имеющих право работать в соответствующем штате. Для этого я изменяю last_asgnmt_dt = sysdate и беру в качестве следующего ответственного за кредит user_id с min(last_asgnmt_dt).

Однако после первоначального распределения нагрузка сотрудников может оказаться разной, в зависимости от количества кредитов, выданных в штате. Как можно было бы взять среднее количество кредитов в штате и поровну распределить их между сотрудниками? Например, в штате TX выдано 400 кредитов. Этим штатом сейчас занимается 4 сотрудника, нагрузка среди которых распределена так:

emp1:             150
emp2:              50
emp3:              75
emp4:               0
нераспределенные: 125.

Я хочу поровну поделить все активные кредиты между 4 сотрудниками.

Ответ Тома Кайта

Как вам такое решение:

ops$tkyte@ORA920LAP> create table user_state_served
  2  as
  3  select rownum user_id, 'TX' state_cd from all_objects where rownum <= 4
  4  union all
  5  select rownum+4 user_id, 'VA' state_cd from all_objects where rownum <= 3;
Table created.

ops$tkyte@ORA920LAP> create table loan_table
  2  as
  3  select 'TX' state_cd, 1 user_id from all_objects where rownum <= 150
  4  union all
  5  select 'TX', 2 from all_objects where rownum <= 50
  6  union all
  7  select 'TX', 3 from all_objects where rownum <= 75
  8  union all
  9  select 'TX', null from all_objects where rownum <= 125;
Table created.

ops$tkyte@ORA920LAP> insert into loan_table
  2  select 'VA', 5 from loan_table
  3  /
400 rows created.

ops$tkyte@ORA920LAP> select user_id, count(*) from loan_table group by user_id
  2  /
   USER_ID   COUNT(*)
---------- ----------
         1        150
         2         50
         3         75
         5        400
                  125

ops$tkyte@ORA920LAP> create or replace procedure redistribute_state(p_state_cd in varchar2)
  2  as
  3      type rowidArray is table of rowid INDEX BY BINARY_INTEGER;
  4
  5      l_user_id  dbms_sql.number_table;
  6      l_rowids   rowidArray;
  7  begin
  8
  9  select b.user_id, a.rid BULK COLLECT into l_user_id, l_rowids
 10    from (
 11  select state_cd,
 12         ntile(buckets) over ( partition by buckets, state_cd order by state_cd ) idx,
 13         loan_table.rowid rid
 14    from loan_table,
 15         (select count(*) BUCKETS
 16            from user_state_served
 17           where state_cd = p_state_cd)
 18   where state_cd = p_state_cd
 19         ) A,
 20         (select user_id, row_number() over ( order by user_id ) rn
 21            from user_state_served
 22           where state_cd = p_state_cd ) b
 23   where a.idx = b.rn;
 24
 25   forall i in 1 .. l_rowids.count
 26       update loan_table set user_id = l_user_id(i) where rowid = l_rowids(i);
 27  end;
 28  /
Procedure created.

ops$tkyte@ORA920LAP> exec redistribute_state( 'TX' );
PL/SQL procedure successfully completed.

ops$tkyte@ORA920LAP> exec redistribute_state( 'VA' );
PL/SQL procedure successfully completed.

ops$tkyte@ORA920LAP> select user_id, count(*) from loan_table group by user_id
  2  /
   USER_ID   COUNT(*)
---------- ----------
         1        100
         2        100
         3        100
         4        100
         5        134
         6        133
         7        133
7 rows selected.

Поскольку в версии 8i функцию ntile в plsql использовать нельзя, вот как можно изменить это решение для версии Oracle 8i:

ops$tkyte@ORA920LAP> rollback;
Rollback complete.

ops$tkyte@ORA920LAP> select user_id, count(*) from loan_table group by user_id
  2  /
   USER_ID   COUNT(*)
---------- ----------
         1        150
         2         50
         3         75
         5        400
                  125

ops$tkyte@ORA920LAP> create or replace view V
  2  as
  3  select b.user_id, a.rid
  4    from (
  5  select state_cd,
  6         ntile(buckets) over ( partition by buckets, state_cd order by state_cd ) idx,
  7         loan_table.rowid rid
  8    from loan_table,
  9         (select count(*) BUCKETS
 10            from user_state_served
 11           where state_cd = userenv('client_info'))
 12   where state_cd = userenv('client_info')
 13         ) A,
 14         (select user_id, row_number() over ( order by user_id ) rn
 15            from user_state_served
 16           where state_cd = userenv('client_info') ) b
 17   where a.idx = b.rn;
View created.

ops$tkyte@ORA920LAP> create or replace procedure redistribute_state(p_state_cd in varchar2)
  2  as
  3      type rowidArray is table of rowid index by binary_integer;
  4
  5      l_user_id  dbms_sql.number_table;
  6      l_rowids   rowidArray;
  7  begin
  8      dbms_application_info.set_client_info(p_state_cd);
  9      select user_id, rid BULK COLLECT into l_user_id, l_rowids
 10        from v;
 11
 12      forall i in 1 .. l_rowids.count
 13          update loan_table set user_id = l_user_id(i) where rowid = l_rowids(i);
 14  end;
 15  /
Procedure created.

ops$tkyte@ORA920LAP> exec redistribute_state( 'TX' );
PL/SQL procedure successfully completed.

ops$tkyte@ORA920LAP> exec redistribute_state( 'VA' );
PL/SQL procedure successfully completed.

ops$tkyte@ORA920LAP> select user_id, count(*) from loan_table group by user_id
  2  /
   USER_ID   COUNT(*)
---------- ----------
         1        100
         2        100
         3        100
         4        100
         5        134
         6        133
         7        133
7 rows selected.

Комментарий читателя от 24 июня 2003 года

Том!

Хранимая процедура работает не совсем так, как мне хотелось бы. Например, у меня есть 6 кредитов для в штате TX:

user_id         loan_id
2               1
3               2
3               3
3               4
3               5
                6

При выполнении твоей хранимой процедуры, она равномерно распределяет 6 кредитов среди 2 пользователей в группе, но меняет уже выделенные сотруднику задания. Например, в данном случае она может взять кредит с идентификатором 1 и передать его для работы сотруднику с user_id 3. Хотя этого не надо делать - надо только забрать кредиты у перегруженных сотрудников и передать для управления менее загруженным, не отбирая у них те кредиты, с которыми они уже работают.

Ответ Тома Кайта

Ну, идею вы поняли, так почему бы не попытаться решить самому?

Ссылки по теме

  
Помощь
Задать вопрос
 программы
 обучение
 экзамены
 компьютеры
Бесплатный звонок
ICQ-консультанты
Skype-консультанты

Общая справка
Как оформить заказ
Тарифы доставки
Способы оплаты
Прайс-лист
Карта сайта
 
Бестселлеры
Курсы обучения "Atlassian JIRA - система управления проектами и задачами на предприятии"
Microsoft Windows 10 Профессиональная 32-bit/64-bit. Все языки. Электронный ключ
Microsoft Office для Дома и Учебы 2019. Все языки. Электронный ключ
Курс "Oracle. Программирование на SQL и PL/SQL"
Курс "Основы TOGAF® 9"
Microsoft Office 365 Персональный 32-bit/x64. 1 ПК/MAC + 1 Планшет + 1 Телефон. Все языки. Подписка на 1 год. Электронный ключ
Курс "Нотация BPMN 2.0. Ее использование для моделирования бизнес-процессов и их регламентации"
 

О нас
Интернет-магазин ITShop.ru предлагает широкий спектр услуг информационных технологий и ПО.

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

Хорошие отзывы постоянных клиентов и высокий уровень специалистов позволяет получить наивысший результат при совместной работе.

В нашем магазине вы можете приобрести лицензионное ПО выбрав необходимое из широкого спектра и ассортимента по самым доступным ценам. Наши менеджеры любезно помогут определиться с выбором ПО, которое необходимо именно вам. Также мы проводим учебные курсы. Мы приглашаем к сотрудничеству учебные центры, организаторов семинаров и бизнес-тренингов, преподавателей. Сфера сотрудничества - продвижение бизнес-тренингов и курсов обучения по информационным технологиям.



 

О нас

 
Главная
Каталог
Новинки
Акции
Вакансии
 

Помощь

 
Общая справка
Как оформить заказ
Тарифы доставки
Способы оплаты
Прайс-лист
Карта сайта
 

Способы оплаты

 

Проекты Interface Ltd.

 
Interface.ru   ITShop.ru   Interface.ru/training   Olap.ru   ITnews.ru  
 

119334, г. Москва, ул. Бардина, д. 4, корп. 3
+7 (495) 229-0436   shopadmin@itshop.ru
Проверить аттестат
© ООО "Interface Ltd."
Продаем программное обеспечение с 1990 года