У меня есть запрос, который генерирует праздники, которые человек зарегистрировал в своем расписании.
Каждый день в расписании представляет собой отдельную запись, но если вы берете неделю отпуска (с 26 декабря 2011 г. по 30 декабря 2011 г.), это должно быть представлено запросом в одном блоке (1 строка).
Вот мой запрос, немного упрощенный для вопроса:
SELECT -1 ord_li_pers_plan_id
,ts.person_id person_id
,-1 order_line_id
,ts.timesheet_dt start_dt
,ts.timesheet_dt end_dt
,'Vacation' project
,null color
,1013011 planning_type
FROM timesheets ts
JOIN persons pers ON ts.person_id = pers.person_id
JOIN person_holidays per_hol ON
ts.person_holiday_id = per_hol.person_holiday_id
JOIN v_holiday_types hoty_peho ON
per_hol.holiday_type_id = hoty_peho.holiday_type_id
WHERE ts.person_holiday_id IS NOT NULL
AND per_hol.holiday_type_id IN (SELECT holiday_type_id FROM v_holiday_types)
AND ts.person_id = :p_person_id
И вот что я получаю сейчас:
-1 11182 -1 30-DEC-11 30-DEC-11 Vacation 1013011
-1 11182 -1 29-DEC-11 29-DEC-11 Vacation 1013011
-1 11182 -1 28-DEC-11 28-DEC-11 Vacation 1013011
-1 11182 -1 27-DEC-11 27-DEC-11 Vacation 1013011
-1 11182 -1 26-DEC-11 26-DEC-11 Vacation 1013011
-1 11182 -1 31-OCT-11 31-OCT-11 Vacation 1013011
-1 11182 -1 02-SEP-11 02-SEP-11 Vacation 1013011
-1 11182 -1 29-JUL-11 29-JUL-11 Vacation 1013011
-1 11182 -1 22-JUL-11 22-JUL-11 Vacation 1013011
-1 11182 -1 25-APR-11 25-APR-11 Vacation 1013011
ОБНОВЛЕНИЕ:
Вместо этого запрос должен вывести следующее:
-1 11182 -1 26-DEC-11 30-DEC-11 Vacation 1013011
-1 11182 -1 31-OCT-11 31-OCT-11 Vacation 1013011
-1 11182 -1 02-SEP-11 02-SEP-11 Vacation 1013011
-1 11182 -1 29-JUL-11 29-JUL-11 Vacation 1013011
-1 11182 -1 22-JUL-11 22-JUL-11 Vacation 1013011
-1 11182 -1 25-APR-11 25-APR-11 Vacation 1013011
Обратите внимание на первый ряд. Теперь он представляет весь отпуск.
ОБНОВЛЕНИЕ 2
Мой клиент предложил другую идею. Этот запрос связан с расписанием со всеми проектами, которым назначен человек. Даты проекта изначально были сохранены в виде блока (1 запись за диапазон дат, например, 01.01.2012 - 01.10.2012 => 1 запись). Теперь клиент хочет сохранить все даты в виде отдельных записей. Это не сложно сделать, и это работает.
Проблема, с которой я сейчас сталкиваюсь, заключается в том, что group by больше не работает, потому что ord_li_pers-plan_id - это PK.
Прилагается запрос. Это довольно большой.
SELECT person_id ,
order_line_id ,
MIN(start_dt) start_dt ,
MAX(end_dt) end_dt ,
project ,
color ,
planning_type,
ord_li_pers_plan_id
FROM
(SELECT ord_li_pers_plan_id ,
person_id ,
order_line_id ,
start_dt ,
end_dt ,
project ,
color ,
planning_type ,
SUM(gap) OVER (PARTITION BY person_id ORDER BY start_dt) contiguous_grp
FROM
(SELECT ord_li_pers_plan_id ,
person_id ,
order_line_id ,
start_dt ,
end_dt ,
project ,
color ,
planning_type ,
CASE
WHEN lag(end_dt) over(PARTITION BY person_id ORDER BY start_dt) + 1 >= start_dt
THEN 0
ELSE 1
END gap
FROM
(SELECT ord_li_pers_plan_id ,
person_id ,
order_line_id ,
start_dt ,
end_dt ,
project ,
color ,
planning_type
FROM
(SELECT op.ord_li_pers_plan_id ord_li_pers_plan_id ,
p.person_id person_id ,
p.order_line_id order_line_id ,
op.start_dt start_dt ,
op.end_dt end_dt ,
pl$planning.prep_tooltip(NVL2(ord.end_customer_id, end_cus.name, cus.name)
|| ' - '
|| NVL2(ord_li.project_cd,ord_li.project_cd,ord.project_cd)
|| ' - '
|| func_tp.name
|| ' - '
|| ROUND((con_tp.contract_tp / 5), 2)
||' - '
|| bl$gen_codes.Name_by_Code_Id (op.planning_type)) project ,
olc.color color ,
op.planning_type planning_type
FROM order_line_person_planning op
JOIN order_line_persons p
ON p.ORDER_LINE_PERSON_ID = op.ORDER_LINE_PERSON_ID
JOIN order_lines ord_li
ON ord_li.order_line_id = p.order_line_id
JOIN orders ord
ON ord.order_id = ord_li.order_id
LEFT JOIN order_line_colors olc
ON olc.order_line_id = ord_li.order_line_id
JOIN customers cus
ON ord.customer_id=cus.customer_id
LEFT JOIN customers end_cus
ON ord.end_customer_id=end_cus.customer_id
LEFT JOIN v_contract_types con_tp
ON ord.contract_type_id=con_tp.contract_type_id
JOIN v_function_types func_tp
ON ord_li.function_id=func_tp.function_id
UNION
SELECT -1 ord_li_pers_plan_id ,
ts.person_id person_id ,
-1 order_line_id ,
ts.timesheet_dt start_dt ,
ts.timesheet_dt end_dt ,
'Vacation' project ,
'#99FF33' color ,
-1 planning_type
FROM hrm_iadvise.timesheets ts
JOIN hrm_iadvise.persons pers
ON ts.person_id = pers.person_id
JOIN hrm_iadvise.person_holidays per_hol
ON ts.person_holiday_id = per_hol.person_holiday_id
JOIN hrm_iadvise.v_holiday_types hoty_peho
ON per_hol.holiday_type_id = hoty_peho.holiday_type_id
WHERE ts.person_holiday_id IS NOT NULL
UNION
SELECT -1 ord_li_pers_plan_id ,
per_hol.person_id person_id ,
-1 order_line_id ,
hol.dt start_dt ,
hol.dt end_dt ,
'Vacation' project ,
'#99FF33' color ,
-1 planning_type
FROM holidays hol
JOIN person_holidays per_hol
ON per_hol.holiday_type_id = hol.holiday_type_id
JOIN countries coty
ON coty.country_id = hol.country_id
WHERE coty.country_cd = 150
)
)
)
)
GROUP BY person_id ,
order_line_id ,
project ,
color ,
planning_type ,
contiguous_grp,
ord_li_pers_plan_id;
Первый запрос получает всех проектов, которым назначен человек
Второй запрос получает все праздники, которые человек уже зарегистрировал
Третий запрос получает всех национальных праздников
Заранее спасибо