Автор Тема: Продолжаем тему правильных циклов (реальная задача из  (Прочитано 7817 раз)

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Как бы вы решали такую задачу?:
Дана таблица.
Колонки:
1. Сотрудник
2. Вид начисления
3. Дата начала
4. Дата окончания

3 и 4 - это период действия начисления (2) по данному сотруднику (1)

например:

1 | 1 | 01.01.2012 | 10.01.2012
1 | 1 | 20.01.2012 | 24.01.2012
2 | 1 | 05.01.2012 | 10.01.2012
2 | 2 | 10.02.2012 | 13.06.2012

По сотруднику #1 были начисления #1 в периодах с 01.01.2012 по 10.01.2012 и с 20.01.2012 по 24.01.2012
По сотруднику #2 было начисление #1 в периоде с 05.01.2012 по 10.01.2012, а также начисление #2 в периоде с 10.02.2012 по 13.06.2012

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

1 | 1 | 01.01.2012 | 10.01.2012
1 | 1 | 05.01.2012 | 24.01.2012

Нужно получить результат в виде таблицы с колонками:
1. Сотрудник
2. Вид начисления
3. Количество дней (с учетом пересечений периодов)

например для таблицы:

1 | 1 | 01.01.2012 | 10.01.2012
1 | 1 | 05.01.2012 | 24.01.2012
2 | 1 | 05.01.2012 | 10.01.2012
2 | 2 | 10.02.2012 | 13.02.2012

результат будет:

1 | 1 | 23
2 | 1 | 5
2 | 2 | 3

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

alexus

  • Гость
Для простоты можно полагать, что исходная таблица отсортирована по первым двум полям.
Сортировать надо, как минимум по трём первым полям, или даже по четырём... если для простоты.

DIzer

  • Гость
... а после сортировки см http://oberspace.dyndns.org/index.php/topic,288.0.html  - любым  методом (в зависимости от степени личной извращенности)

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Для простоты можно полагать, что исходная таблица отсортирована по первым двум полям.
Сортировать надо, как минимум по трём первым полям, или даже по четырём... если для простоты.

Да как угодно в общем.
Вопрос старый: Какой цикл самый правильный? (и нужен ли тут цикл вообще)

Peter Almazov

  • Sr. Member
  • ****
  • Сообщений: 482
    • Просмотр профиля
Выходные и праздники, видимо, надо исключить?

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
В реальной задаче нужно было. Но тут не надо.

albobin

  • Full Member
  • ***
  • Сообщений: 198
    • Просмотр профиля
Вопрос старый: Какой цикл самый правильный?
Самый правильный это в МАМПСе, потому что я в нём работаю и эта задачка решается  там влёт без особых мозговых усилий  :D

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Код в студию!

albobin

  • Full Member
  • ***
  • Сообщений: 198
    • Просмотр профиля
Ну, код может убить впечатлительного человека.   :)
А словами можно описать так, естественно используя привычную мне терминологию.

Есть исходный массив (сортирован или не сортирован значения не имеет)
Перебирая все записи этого массива (получая при этом #чела,  #начисл, дата_с, дата_по)
Пишем в временный массив TMP(#чела,#начисл)  строку флагов дней в году
Затем перебирая этот массив заменяем строку флагов на к-во единиц в строке

Грубо говоря - две строки на МАМПСе


valexey

  • Administrator
  • Hero Member
  • *****
  • Сообщений: 1990
    • Просмотр профиля
Ну, код может убить впечатлительного человека.   :)
Да, код на мапсе лучше в пятницу публиковать, ближе к вечеру :-)
"но сейчас, чтобы компенсировать растущую мощность компьютеров, программисты используют фреймворки"

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Ну вы прям классическое решение задачи о покрытиях описали.  :)

Может кто иначе решение предложит.

ps А код все равно хотелось бы увидеть (тем более на таком экзотичном языке)

DIzer

  • Гость
SELECT Sotr, Nach, count(Nach) FROM TABLE
GROUP BY Sotr, Nach
WHERE  Data not in [...] //  исключение праздников
ORDER BY Sotr, Nach
- где то так...
« Последнее редактирование: Август 02, 2012, 02:14:37 pm от DIzer »

DIzer

  • Гость
разумеется это решение верно ТОЛЬКО в том случае когда в один день сотруднику было сделано не более одного однотипного начисления...

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Но это не решение поставленной задачи.
Нужно считать дни в периодах.

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Продолжаем тему правильных циклов
« Ответ #14 : Август 02, 2012, 02:23:54 pm »
На SQL в общем решается так же как описал albobin. (с привлечением дополнительной таблицы-календаря, или, иначе говоря, тупо списка всех дней в году)