2013-11-02 6 views
0

Задача: У меня есть информация о зарплате, хранящаяся в таблице. Мне нужно отображать один результат в год. Для каждого года я хочу отобразить максимальную датированную запись за предыдущий год. Проблема в том, что несколько лет не имеют данных (зарплата не изменилась). Мне нужно, чтобы эти строки содержали максимальную запись до этого года (это может быть от 2 лет до или даже 3).SQL Результаты поиска по году

Мой запрос прямо сейчас будет работать, если в каждой строке есть данные ... но он не учитывает годы, когда данных нет. Как я могу обновить эту SQL тянуть желаемые результаты ниже:

Примера данных:

sch_sal_svc.beg_date ------- sch_sal_svc.beg_date.per_plan_data

  • 1/1/2007 --- 100
  • 6/1/2007 --- 200
  • 1/1/2008 --- 300
  • 1/1/2011 --- 400
  • 8/1/2011 --- 500
  • 9/1/2012 --- 600

РЕЗУЛЬТАТЫ

  • 1/1/2008 --- 200
  • 1/1/2011 --- 300
  • 1/1/2012 --- 500

желаемых результатов

  • 1/1/2008 --- 200
  • 1/1/2009 --- 300
  • 1/1/2010 --- 300
  • 1/1/2011 --- 300
  • 1/1/2012 --- 500

SQL:

SELECT 
years.control_id, 
years.ssn, 
ebe.plan_id, 
to_number(to_char(years.sal_date,'yyyy')), 
null as per_plan_salary, 
    null as per_vest_hours, 
    null as per_credsvc_hours, 
    LEAST(s.rate_1,cl.comp_genl), 
    null as salary_1, 
    null as per_comm, 
    null as per_overtime, 
    null as per_ncr, 
    null as salary_2 
FROM 
    sch_sal_svc s 
    , (select distinct ssn, control_id, TRUNC(beg_date,'YEAR') as sal_date from sch_sal_svc where beg_date > to_date('12/31/1900', 'mm/dd/yyyy')) years 
    , employee_benefit_elig ebe, compliance_limits cl 
WHERE 
    years.ssn = ebe.ssn 
    and years.control_id = ebe.control_id 
    and to_number(to_char(years.sal_date,'yyyy')) = cl.limit_year 
    and to_number(to_char(years.sal_date,'yyyy')) <= to_number(to_char(sysdate,'yyyy')) 
    and s.beg_date = (
     select max(s2.beg_date) from sch_sal_svc s2 
     where s2.ssn = years.ssn and s2.control_id = years.control_id 
     and s2.beg_date <= years.sal_date 
    ) 
    and s.ssn = years.ssn 
    and s.control_id = years.control_id 
    and ebe.benefit_id = 'DB' 
    and ebe.control_id = 'CLIENT' 
    and ebe.plan_id in ('100', '200') 
+4

Вот хороший совет для написания SQL-вопросов в Stackoverflow, используйте http://sqlfiddle.com/ для создания «Примерной базы данных» и отправьте ссылку в вопросе, это позволит вам и людям размещать ответы «проверить их работу «чтобы увидеть результат запроса - это то, что вы ищете. Также, чтобы получить привлекательные таблицы, например, результирующие наборы используют [этот сайт] (http://www.sensefulsolutions.com/2010/10/format-text-as-table.html) (созданный пользователем SO [Sensful] (http : //meta.stackoverflow.com/users/143909/senseful)) и оберните таблицу в '

' html tags –
                        
                            
                                
                            
                        
                    

ответ

0
CREATE TABLE sch_sal_svc 
(
    beg_date  DATE 
, per_plan_data NUMBER 
); 


INSERT INTO sch_sal_svc VALUES(TO_DATE('01/01/2007', 'DD/MM/YYYY'), 100); 
INSERT INTO sch_sal_svc VALUES(TO_DATE('06/01/2007', 'DD/MM/YYYY'), 200); 
INSERT INTO sch_sal_svc VALUES(TO_DATE('01/01/2008', 'DD/MM/YYYY'), 300); 
INSERT INTO sch_sal_svc VALUES(TO_DATE('01/01/2011', 'DD/MM/YYYY'), 400); 
INSERT INTO sch_sal_svc VALUES(TO_DATE('08/01/2011', 'DD/MM/YYYY'), 500); 
INSERT INTO sch_sal_svc VALUES(TO_DATE('09/01/2012', 'DD/MM/YYYY'), 600); 


SELECT MIN(beg_date) FROM sch_sal_svc; 
-- 2007-01-01 00:00:00 


SELECT d.r_level + NUMTOYMINTERVAL(1, 'YEAR') AS d_date 
,  NVL -- the salary must be updated at least once in three years 
     (
      NVL 
      (
       NVL 
       (
        s.per_plan_data 
       , LAG(s.per_plan_data, 1) OVER (PARTITION BY 1 ORDER BY d.r_level) 
       ) 
      , LAG(s.per_plan_data, 2) OVER (PARTITION BY 1 ORDER BY d.r_level) 
      ) 
     , LAG(s.per_plan_data, 3) OVER (PARTITION BY 1 ORDER BY d.r_level) 
     ) AS lag_per_plan_data 
FROM 
(
     SELECT DATE'2006-01-01' + NUMTOYMINTERVAL(LEVEL, 'YEAR') AS r_level -- min beg_date minus 1 
     FROM DUAL 
     CONNECT BY 
       LEVEL < (SELECT TO_CHAR(MAX(beg_date), 'YYYY') - TO_CHAR(MIN(beg_date), 'YYYY') + 2 FROM sch_sal_svc) 
) d 
LEFT JOIN 
(
     SELECT beg_date 
     ,  per_plan_data 
     FROM sch_sal_svc 
     WHERE (beg_date) IN 
       (
        SELECT MAX(beg_date) 
        FROM sch_sal_svc 
        GROUP BY 
          TRUNC(beg_date, 'YYYY') 
       ) 
) s 
ON  d.r_level = TRUNC(s.beg_date, 'YYYY') 
; 

/* 
2008-01-01 00:00:00 200 
2009-01-01 00:00:00 300 
2010-01-01 00:00:00 300 
2011-01-01 00:00:00 300 
2012-01-01 00:00:00 500 
2013-01-01 00:00:00 600 
*/ 
Смежные вопросы