2013-11-02 35 views
0

問題:我記錄了存儲在表中的工資信息。我需要每年顯示一個結果。每年,我想顯示前一年的最大日期記錄。問題是有些年份沒有數據(薪水沒有變化)。我需要這些行來包含該年之前的最大記錄(可能是2年前甚至3年)。SQL拉結果

我的查詢現在可以工作,如果每一行都有數據...但它沒有考慮到沒有數據的年份。如何更新此SQL拉低於所期望的結果:數據的

實施例:

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

  • 1/1/2007 --- 100
  • 2007年6月1日--- 200
  • 1/1/2008 --- 300
  • 1/1/2011 --- 400
  • 2011年8月1日--- 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

這裏是一個很好的提示,用於在Stackoverflow上編寫SQL問題,使用http://sqlfiddle.com/創建一個「示例數據庫」並在問題中發佈鏈接,這會讓你和人員張貼答案「檢查他們的工作「查看查詢的輸出是你在哪裏尋找的。同樣爲了獲得好看的表格,例如結果集使用[本網站](http://www.sensefulsolutions.com/2010/10/format-text-as-table.html)(由SO用戶創建[Sensful](http ://meta.stackoverflow.com/users/143909/senseful)),並在'

'html標籤中包裝表格 –
                        
                            
                                
                            
                        
                    

回答

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 
*/