Имам изискване да извлека списък със служители и за всеки служител списък с месеци, в които са били активно в покритието на обезщетенията през дадена година. Има таблица с данни за работата и таблица с информация за предимствата. Има и таблица с доставени дати, която изброява всяка дата от 2007-2018 г. и за всяка дата показва деня от месеца, месеца от годината и календарната година.
Начинът, по който написах заявката сега, е да кажа: намерете всички дати в таблицата с дати, които са 1) между 01/01 и 12/31 от подканата година (или текущата дата, която от двете е по-стара), 2) по време на времето, през което служителят е бил активен в таблицата с доходи. За всяка дата искам също дептида от таблицата с работни места и плана за доходи от таблицата с доходи към тази дата. След това правя отделен, показващ само месеца от годината и календарната година за всеки служител.
Това работи, но проблемът идва, когато се опитам да го направя за отдели с много хора в тях. Отнема много време, за да се изпълнява, вярвам, защото извлича до 365 реда за всеки отделен служител и след това показва само 12 от тях, тъй като изтегля само отделни месеци. Чувствам, че има по-добър начин да направя това, но не мога да се сетя какъв е той.
Ето някои опростени примери за таблиците, с които работя:
Таблица с дати
THE_DATE MONTHOFYEAR CALENDAR_YEAR
01-OCT-15 10 2015
02-OCT-15 10 2015
03-OCT-15 10 2015
...
Таблица с работни места
(A=Активен; I=Неактивен)
EMPLID EFFDT DEPTID HR_STATUS
00123 01-FEB-15 900 A
00123 30-JUN-15 900 I
00123 01-AUG-15 901 A
Таблица с предимствата
EMPLID EFFDT BENEFIT_PLAN STATUS
00123 01-MAR-15 PPO A
00123 31-JUL-15 I
00123 01-SEP-15 HMO A
Желан резултат
EMPLID CALENDAR_YEAR MONTHOFYEAR DEPTID BENEFIT_PLAN
00123 2015 3 900 PPO
00123 2015 4 900 PPO
00123 2015 5 900 PPO
00123 2015 6 900 PPO
00123 2015 7 900 PPO
00123 2015 9 901 HMO
00123 2015 10 901 HMO
00123 2015 11 901 HMO
^ (shows November row even though employee was only covered for part of this month)
Примерен SQL за получаване на резултати по-горе
SELECT DISTINCT J.EMPLID, D.CALENDAR_YEAR, D.MONTHOFYEAR, J.DEPTID, B.BENEFIT_PLAN
FROM DATES D,
JOBS J
JOIN
BENEFITS B
ON J.EMPLID = B.EMPLID
WHERE D.THE_DATE <= SYSDATE
AND D.THE_DATE BETWEEN
TO_DATE(:YEAR_PROMPT || '01-01', 'YYYY-MM-DD')
AND
TO_DATE(:YEAR_PROMPT || '12-31', 'YYYY-MM-DD')
AND B.STATUS = 'A'
AND D.THE_DATE BETWEEN
B.EFFDT
AND
NVL(SELECT MIN(B_ED.EFFDT)
FROM BENEFITS B_ED
WHERE B_ED.EMPLID = B.EMPLID
AND B_ED.EFFDT > B.EFFDT
, SYSDATE)
AND J.EFFDT = (SELECT MAX(J_ED.EFFDT)
FROM JOBS J_ED
WHERE J_ED.EMPLID = J.EMPLID
AND J_ED.EFFDT <= D.THE_DATE)
Вместо да казвам „извлечете всяка отделна дата и проверете дали отговаря на критериите“, мога ли да променя логиката по някакъв начин, за да получа същите резултати, без да преминавам през толкова много редове?
cross join
качитеdates
иjobs
маси. - person Vamsi Prabhala   schedule 05.11.2015