【问题标题】:Working with effective dated records使用有效日期记录
【发布时间】:2009-03-06 00:30:19
【问题描述】:

如何获取员工,比如 5 个最新的 Action_reason 行,它们在有效日期的记录中,没有未来的行,应该只选择当前和历史行(生效日期

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.

【问题讨论】:

  • 为什么要单行?对于只有 4 个操作原因行的人,您希望行中的内容是什么? 3、2、1、0?使用@Quasssnoi 的解决方案提供的每位员工 0 到 5 行的表格不是更好吗?
  • 0 和 5 行将获取员工的最新 5 行,但操作原因可能相同。我想获取 5 个最新的行动理由;如果他们只有 2-3 行更改,那么其他两个将空白。这是为了报告目的。

标签: oracle peoplesoft


【解决方案1】:
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

【讨论】:

  • 如何在一行中获取员工(假设 5 个操作)从最新到最后的操作以及相应的 effdts,但不是工作的最后 5 行
  • 对不起,我不太明白你想要什么。请在您的问题中发布一些示例数据和所需的结果。
  • 他想要:emplid, effdt1, act1, effdt2, act2, effdt3, act3, ...;当然,这不是一个特别好的主意。
  • 是的,但这是客户要求。我需要你的帮助,所以完成任务。
【解决方案2】:
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

【讨论】:

    【解决方案3】:

    您可以按照自己的意愿获取数据。如果你想要它为五行,那么你可以使用这个:

    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
    

    如果您希望数据全部在一行中,则使用 Oracle 的 LAG 分析功能,因此:

    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 值和最后 5 个操作原因值。如果两个都不需要,上面的 SQL 可以做相应的修剪。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-18
      • 2017-05-22
      • 2021-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多