2009-03-03 13 views
0

Çalışanlar nasıl alınır, efektif geçmiş tarihli 5 sonuncu Action_reason satırı, gelecek satır yok, yalnızca geçerli ve geçmiş satırları seçmelidir (etkin tarih < = sysdate). Bunları tek sıra halinde alabilir miyim, yoksa bir Çalışan için 5 satır mı olacak?Etkin tarihli kayıtlarla çalışma

select emplid, effdt, action_reasons 
-- we have to build a logic here. 
-- Should we initialize 5 ACT variables to fetch rows into it? 
-- Please help 
from JOB 
where emplid = '12345' 
    and effdt <= sysdate. 
+0

Neden tek bir satır istiyorsun? Sadece 4 eylem nedeni satırı olan insanlar için satırlarda ne istiyorsunuz? 3, 2, 1, 0? @ Quasssnoi'nin çözümünün sağladığı gibi, çalışan başına 0 ile 5 satır arasında bir tabloyla daha iyi olamaz mıydınız? –

+0

0 ve 5 satır, bir çalışanın en son 5 satırını alır, ancak eylem nedeni aynı olabilir. En son 5 Eylem Nedenini almak istiyorum; eğer sadece 2-3 değişmiş satır varsa, diğer ikisi boş olacaktır. Ve bu, raporlama amaçlıdır. –

cevap

3
SELECT LTRIM(SYS_CONNECT_BY_PATH(emplid || ', ' || effdt || ', ' || action_reasons, ', '), ', ') 
FROM (
     SELECT 
     FROM (
      SELECT emplid, effdt, action_reasons, ROW_NUMBER() OVER (ORDER BY effdt) AS rn 
      FROM JOB 
      WHERE emplid= '12345' 
       AND effdt <= SYSDATE 
      ) 
     WHERE rn <= 5 
     ) 
WHERE CONNECT_BY_ISLEAF = 1 
START WITH 
    rn = 1 
CONNECT BY 
    rn = PRIOR rn + 1 
+0

Çalışan (5 eylemleri) tek bir satırda en sondan son eylemlere kadar ilgili efeklerle nasıl elde edilir, ancak işin son 5 satırı değil –

+0

Üzgünüz, ne istediğinizi tam olarak anlayamıyorum. Lütfen sorunuzda bazı örnek verileri ve istenen sonucu yayınlayın. – Quassnoi

+0

İstediği: emplid, effdt1, act1, effdt2, act2, effdt3, act3, ...; Tabi ki bu özellikle iyi bir fikir değil. –

0
SELECT JOBXX.EMPLID,JOBXX.EFFDT,JOBXX.ACT1,JOBXX.ACT2,JOBXX.ACT3,JOBXX.ACT4,JOBXX.ACT5 
FROM 
    (SELECT SD.EMPLID, 
      SD.EFFDT, 
      CHR(SUBSTR(TO_CHAR(SUM(CASE WHEN SD.R3 = 1 THEN SD.A1 ELSE 0 END)),1,2)) || 
      CHR(SUBSTR(TO_CHAR(SUM(CASE WHEN SD.R3 = 1 THEN SD.A1 ELSE 0 END)),3,2)) || 
      CHR(SUBSTR(TO_CHAR(SUM(CASE WHEN SD.R3 = 1 THEN SD.A1 ELSE 0 END)),5,2)) 
      AS ACT1, 
      CHR(SUBSTR(TO_CHAR(SUM(CASE WHEN SD.R3 = 2 THEN SD.A1 ELSE 0 END)),1,2)) || 
      CHR(SUBSTR(TO_CHAR(SUM(CASE WHEN SD.R3 = 2 THEN SD.A1 ELSE 0 END)),3,2)) || 
      CHR(SUBSTR(TO_CHAR(SUM(CASE WHEN SD.R3 = 2 THEN SD.A1 ELSE 0 END)),5,2)) 
      AS ACT2, 
      CHR(SUBSTR(TO_CHAR(SUM(CASE WHEN SD.R3 = 3 THEN SD.A1 ELSE 0 END)),1,2)) || 
      CHR(SUBSTR(TO_CHAR(SUM(CASE WHEN SD.R3 = 3 THEN SD.A1 ELSE 0 END)),3,2)) || 
      CHR(SUBSTR(TO_CHAR(SUM(CASE WHEN SD.R3 = 3 THEN SD.A1 ELSE 0 END)),5,2)) 
      AS ACT3, 
      CHR(SUBSTR(TO_CHAR(SUM(CASE WHEN SD.R3 = 4 THEN SD.A1 ELSE 0 END)),1,2)) || 
      CHR(SUBSTR(TO_CHAR(SUM(CASE WHEN SD.R3 = 4 THEN SD.A1 ELSE 0 END)),3,2)) || 
      CHR(SUBSTR(TO_CHAR(SUM(CASE WHEN SD.R3 = 4 THEN SD.A1 ELSE 0 END)),5,2)) 
      AS ACT4, 
      CHR(SUBSTR(TO_CHAR(SUM(CASE WHEN SD.R3 = 5 THEN SD.A1 ELSE 0 END)),1,2)) || 
      CHR(SUBSTR(TO_CHAR(SUM(CASE WHEN SD.R3 = 5 THEN SD.A1 ELSE 0 END)),3,2)) || 
      CHR(SUBSTR(TO_CHAR(SUM(CASE WHEN SD.R3 = 5 THEN SD.A1 ELSE 0 END)),5,2)) 
      AS ACT5 
    FROM (
     SELECT EMPLID,EFFDT,ACTION_REASON, 
       SUBSTR(ACTION_REASON,1,1), 
       SUBSTR(ACTION_REASON,2,1), 
       SUBSTR(ACTION_REASON,3,1), 
       TO_NUMBER(ASCII(SUBSTR(ACTION_REASON,1,1)) || 
       ASCII(SUBSTR(ACTION_REASON,2,1)) || 
       ASCII(SUBSTR(ACTION_REASON,3,1))) AS A1, 
       ROW_NUMBER() over(PARTITION BY EMPLID,EFFDT ORDER BY EFFDT desc,EFFSEQ desC) R3 
     FROM PS_JOB 
     WHERE action in ('ABC','XYZ') 
     and action_reason in ('123','456','789') 
     and emplid IN('12345','ABCDE') 
     AND effdt between '01-jan-2008' and '18-dec-2008' 
     ORDER BY EFFDT DESC, EFFSEQ DESC 
    ) SD       
    GROUP BY EMPLID , EFFDT    
) JOBXX 
0

Verileri istediğiniz şekilde sahip olabilir. Sonra Oracle'ın LAG analitik işlevi kullanmak tek bir satırda verilerin tüm istiyorsanız böylece

select * from (
      select emplid, empl_rcd, effdt, action_reason 
        , rank() over (partition by emplid, empl_rcd 
           order by effdt desc, effseq desc) rank1 
       from ps_job 
       where emplid = '12345' 
       and effdt <= sysdate) 
where rank1 <= 5 

: Beş satır olarak isterseniz o zaman bu kullanabilirsiniz Bu son verir

select * from ( 
    select emplid, empl_rcd, effdt 
     , lag(effdt) over(partition by emplid, empl_rcd order by effdt, effseq) effdt_lag1 
     , lag(effdt, 2) over(partition by emplid, empl_rcd order by effdt, effseq) effdt_lag2 
     , lag(effdt, 3) over(partition by emplid, empl_rcd order by effdt, effseq) effdt_lag3 
     , lag(effdt, 4) over(partition by emplid, empl_rcd order by effdt, effseq) effdt_lag4 
     , action_reason 
     , lag(action_reason) over(partition by emplid, empl_rcd order by effdt, effseq) action_reason_lag1 
     , lag(action_reason, 2) over(partition by emplid, empl_rcd order by effdt, effseq) action_reason_lag2 
     , lag(action_reason, 3) over(partition by emplid, empl_rcd order by effdt, effseq) action_reason_lag3 
     , lag(action_reason, 4) over(partition by emplid, empl_rcd order by effdt, effseq) action_reason_lag4 
     from ps_job 
    where emplid = '12345') j 
where effdt = (
      select max(j1.effdt) from ps_job j1 
      where j1.emplid = j.emplid 
       and j1.empl_rcd = j.empl_rcd 
       and j1.effdt <= sysdate) 

5 effdt değeri ve son 5 eylem nedeni değerleri. Yukarıdaki SQL'e ihtiyacınız yoksa, buna göre kesilebilir.