【问题标题】:PL/SQL- Query to get Start and End date Based on column ValuesPL/SQL-根据列值查询开始和结束日期
【发布时间】:2016-03-13 20:49:45
【问题描述】:

我有一个按月列出的员工存在数据列表(Exist='T',Not Exist ='F'),数据如下所示。

DepNo   Empno   Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
---------------------------------------------------------------
1234    100     T   T   T   T   T   T   T   F   F   F   F   F
1234    101     T   T   T   T   F   F   F   F   F   F   F   F
1234    102     F   F   F   F   T   T   T   T   T   T   T   T
1234    103     F   F   F   F   T   T   T   F   F   F   F   F
---------------------------------------------------------------

我想获取每位员工的开始和结束日期。例如,员工 100 的开始日期是 2015 年 1 月 1 日(因为他存在于 1 月),结束日期是 2015 年 7 月 31 日(因为员工在 8 月被终止

---------------------------------------------------------------------------------
DepNo   Empno   Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec StartDt EndDt
----------------------------------------------------------------------------------
1234    100     T   T   T   T   T   T   T   F   F   F   F   F   1-Jan-15 31-Jul-15
1234    101     T   T   T   T   F   F   F   F   F   F   F   F   1-Jan-15 30-Apr-15
1234    102     F   F   F   F   T   T   T   T   T   T   T   T   1-May-15 31-Dec-15
1234    103     F   F   F   F   T   T   T   F   F   F   F   F   1-May-15 31-Jul-15
----------------------------------------------------------------------------------

我正在使用 Oracle 11g。有人可以帮我实现这一目标吗?

【问题讨论】:

  • Nivas,选择....案例不起作用。因为使用 select....case 1st-row 返回 enddt 为 2015 年 11 月 30 日,但我需要 2015 年 7 月 31 日。如果我看起来有问题,请纠正我
  • 可以将单个 SQL 与 select case 一起使用,但这会变得过于复杂。如果您可以使用 PL/SQL,我建议您这样做。如果我能得到一个不错的答案,我会尝试编写 SQL 并将其发布为答案。
  • 您还必须更清楚您的假设。您可以让同一员工在TF 之间来回多次吗?员工可以只有Fs 吗?遇到这种情况怎么办?是否假定月份为年份2015
  • 如果你能发布你到目前为止所尝试的内容,我也很高兴。包括您尝试使用select ... case

标签: oracle plsql oracle11g


【解决方案1】:

准备环境。

create table tab1(depno number,empno number, jan char(1),feb char(1),mar char(1),apr char(1),may char(1),jun char(1),jul char(1),aug char(1),sep char(1),oct char(1),nov char(1),dec char(1));
insert into tab1 values(1234,100,'T','T','T','T','T','T','T','F','F','F','F','F');
insert into tab1 values(1234, 101,'T','T','T','T','F','F','F','F','F','F','F','F');
insert into tab1 values(1234, 102,'F','F','F','F','T','T','T','T','T','T','T','T');
insert into tab1 values(1234,103,'F','F','F','F','T','T','T','F','F','F','F','F');

运行此查询

select tab1.*,t3.startd,t3.endd from tab1, (select depno,empno,min(to_date('2015.'||monthh1||'.01','yyyy.mm.dd')) as startd, max(add_months(to_date('2015.'||monthh1||'.01','yyyy.mm.dd'),1)-1) as endd from (select t1.depno,t1.empno,decode(monthh,'JAN',1,'FEB',2,'MAR',3,'APR',4,'MAY',5,'JUN',6,'JUL',7,'AUG',8,'SEP',9,'OCT',10,'NOV',11,'DEC',12,-1) monthh1,statee from (select * from tab1 unpivot (statee for monthh in(jan,feb,mar,apr,may,jun,jul,aug,sep,oct,nov,dec))) t1) t2 where statee='T' group by depno,empno)t3 where tab1.depno=t3.depno and tab1.empno=t3.empno order by tab1.depno,tab1.empno

享受吧。

【讨论】:

    【解决方案2】:

    你可以试试这样的。请注意,我强烈建议不要这样做并使用 PL/SQL 或其他一些编程语言作为逻辑。 我还没有测试过这个(还)。我将根据我的测试(或删除我的答案)逻辑进行更新。作品。已添加 SQLfiddle。

    (http://sqlfiddle.com/#!4/30fc1/12):

     select e.empno, 
           1 start_day, 
           (case when EXTRACT(month FROM e.StartDt) > t.start_month 
                 then EXTRACT(month FROM e.StartDt) 
                 else t.start_month end) start_month, 
           EXTRACT(year FROM e.StartDt) start_year,
           to_date(1  || '-' ||
           (case when EXTRACT(month FROM e.StartDt) > t.start_month 
                 then EXTRACT(month FROM e.StartDt) 
                 else t.start_month end) || '-' ||
           EXTRACT(year FROM e.StartDt), 'dd-mm-yyyy') start_date
    from employee e, 
         (select empno, 
                 decode(Jan, 'T', 1, 
                 decode(Feb, 'T', 2, 
                 decode(Mar, 'T', 3, 
                 decode(Apr, 'T', 4, 
                 decode(May, 'T', 5, 
                 decode(Jun, 'T', 6, 
                 decode(Jul, 'T', 7, 
                 decode(Aug, 'T', 8, 
                 decode(Sep, 'T', 9, 
                 decode(Oct, 'T', 10, 
                 decode(Nov, 'T', 11, 
                 decode(Decm, 'T', 12, 0)))))))))))) start_month
           from employee) t
    where e.empno = t.empno
    

    您可以根据这个想法获得结束日期。同样,如果可以避免,请不要使用它。

    【讨论】:

      【解决方案3】:

      您好刚刚尝试了解决此问题的非常简单的方法。希望它 有帮助。如有任何问题,请告诉我。

          ALTER SESSION SET NLS_DATE_FORMAT = 'DD/MM/YYYY';
      
          SELECT a.EMPNO,
            to_date('01/'
            ||COALESCE(DECODE(a.dec,'F',NULL,'12/'),DECODE(a.nov,'F',NULL,'11/'),DECODE(a.oct,'F',NULL,'10/'),DECODE(a.sep,'F',NULL,'09/'),DECODE(a.aug,'F',NULL,'08/'),DECODE(a.jul,'F',NULL,'07/'),DECODE(a.june,'F',NULL,'06/'),DECODE(a.MAY,'F',NULL,'05/'),DECODE(a.april,'F',NULL,'04/'),DECODE(a.march,'F',NULL,'03/'),DECODE(a.feb,'F',NULL,'02/'),DECODE(a.jan,'F',NULL,'01/'))
            ||extract(YEAR FROM sysdate),'DD/MM/yyyy') STR,
            TO_DATE('01/'
            ||COALESCE(DECODE(a.dec,'F',NULL,'12/'),DECODE(a.nov,'F',NULL,'11/'),DECODE(a.oct,'F',NULL,'10/'),DECODE(a.sep,'F',NULL,'09/'),DECODE(a.aug,'F',NULL,'08/'),DECODE(a.jul,'F',NULL,'07/'),DECODE(a.june,'F',NULL,'06/'),DECODE(a.MAY,'F',NULL,'05/'),DECODE(a.april,'F',NULL,'04/'),DECODE(a.march,'F',NULL,'03/'),DECODE(a.feb,'F',NULL,'02/'),DECODE(a.jan,'F',NULL,'01/'))
            ||extract(YEAR FROM sysdate),'DD/MM/yyyy') ED_DT
          FROM
            (SELECT 10 AS DPT,
              1 EMPNO,
              'T' AS jan,
              'T' AS feb,
              'T' AS march,
              'T' AS april,
              'T' AS may,
              'T' AS JUNE,
              'T' AS jul,
              'F' AS aug,
              'F' AS sep,
              'F' AS oct,
              'F' AS nov,
              'F' AS DEC
            FROM dual
            UNION ALL
            SELECT 10 AS DPT,
              2 EMPNO,
              'T' AS jan,
              'T' AS feb,
              'T' AS march,
              'T' AS april,
              'F' AS may,
              'F' AS JUNE,
              'F' AS jul,
              'F' AS aug,
              'F' AS sep,
              'F' AS oct,
              'F' AS nov,
              'F' AS DEC
            FROM dual
            UNION ALL
            SELECT 10 AS DPT,
              3 EMPNO,
              'F' AS jan,
              'F' AS feb,
              'F' AS march,
              'F' AS april,
              'T' AS may,
              'T' AS JUNE,
              'T' AS jul,
              'T' AS aug,
              'T' AS sep,
              'T' AS oct,
              'T' AS nov,
              'T' AS DEC
            FROM dual
            UNION ALL
            SELECT 10 AS DPT,
              4 EMPNO,
              'F' AS jan,
              'F' AS feb,
              'F' AS march,
              'F' AS april,
              'T' AS may,
              'T' AS JUNE,
              'T' AS jul,
              'F' AS aug,
              'F' AS sep,
              'F' AS oct,
              'F' AS nov,
              'F' AS DEC
            FROM dual
            )A;
      
      -------------------------------OUTPUT-----------------------------------------
      
      EMPNO     STR              ED_DT
      1   01/07/2015  01/07/2015
      2   01/04/2015  01/04/2015
      3   01/12/2015  01/12/2015
      4   01/07/2015  01/07/2015
      
      -------------------------------OUTPUT-----------------------------------------
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-04-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多