公司要统计每天每人处理业务的真实用时,如果暂时定义的班次只有上下午两班,
第一班:8点上班,中午休息12点
第二班:13点上班,17点下班
休息时间不要计算,求当前时间sysdate到已知开始时间的真实时间差,这个时间可能在一天内的任何时间点我建了一个表来报保存了班次及时间段,在写function的时候发现还是很复杂才能判断这个时间到底落在那个班次或者班次间,有经验的人给点意见
建表语句:
-- Create table
create table WORKINGSCHEDULE
(
  WORKINGSCHEDULEID NUMBER not null,
  DESCRIPTION       VARCHAR2(50),
  HASLD             NUMBER not null,
  CUSTSCHEDULEID    NUMBER,
  CUSTSTARTTIME     DATE,
  CUSTENDTIME       DATE,
  ROWSTAMP          VARCHAR2(40) not null
)
tablespace MAXIMO
  pctfree 10
  initrans 1
  maxtrans 255
  storage
  (
    initial 64
    minextents 1
    maxextents unlimited
  );
-- Create/Recreate indexes 
create unique index WORKINGSCHED_NDX1 on WORKINGSCHEDULE (WORKINGSCHEDULEID)
  tablespace MAXIMO
  pctfree 10
  initrans 2
  maxtrans 255
  storage
  (
    initial 64K
    minextents 1
    maxextents unlimited
  );-----------------------------------------下面是插入了两条数据代表两个班次
insert into workingschedule (WORKINGSCHEDULEID, DESCRIPTION, HASLD, CUSTSCHEDULEID, CUSTSTARTTIME, CUSTENDTIME, ROWSTAMP)
values (1, '1班', 1, 1, to_date('30-12-1899 08:00:00', 'dd-mm-yyyy hh24:mi:ss'), to_date('30-12-1899 12:00:00', 'dd-mm-yyyy hh24:mi:ss'), '5668479');insert into workingschedule (WORKINGSCHEDULEID, DESCRIPTION, HASLD, CUSTSCHEDULEID, CUSTSTARTTIME, CUSTENDTIME, ROWSTAMP)
values (2, '2班', 1, 2, to_date('30-12-1899 13:00:00', 'dd-mm-yyyy hh24:mi:ss'), to_date('30-12-1899 17:00:00', 'dd-mm-yyyy hh24:mi:ss'), '5668482');

解决方案 »

  1.   

    由于不知道oracle如何输入只有时间部分的数据类型,用了date了代替,处理时要做拆分
      

  2.   

    默认周末不上班
    ,我另外有一个表workingday报错了调休的情况,这个排除不是问题,我是想快速简单的sql来得到当前时间在多个班次中的那个班次,返回已经用了多少时间(可以用具体一天来计算)
      

  3.   

    高版本的oracle新语句我不懂,可能用新语句解决,这只提供给你一个适用于高低版本的解决思路:
    把上班时间表(tab1)设计成“班次”,“起始时间”(数字型)两字段,记录如下:
    班次1    8
    班次1    9
    班次1    10
    班次1    11
    班次2    13
    班次2    14
    班次2    15
    班次2    16
    找一个有足够记录数的表如表A
    以下语句则会显示指定起始时间至指定终止时间间的小时数,一条代表一个小时。
    select to_char(b.startdate + a.id / 24,'hh24') as hour,to_char(b.startdate + a.id / 24,'d') as week from
    (select rownum as id from a where rownum <= 你认为可能最大的小时间隔数) a,
    (select 指定的起始时间 as startdate,指定终止时间 as enddate from dual) b
    where b.startdate + a.id / 24 < b.enddate;
    与tab1连接使用则会显示出指定时间区间的小时数:
    select count(*) as "小时数" from tab1,
     (select to_char(b.startdate + a.id / 24,'hh24') as hour,to_char(b.startdate + a.id / 24,'d') as week from
       (select rownum as id from a where rownum <= 你认为可能最大的小时间隔数) a,
       (select 指定的起始时间 as startdate,指定终止时间 as enddate from dual) b
      where b.startdate + a.id / 24 < b.enddate) aa
    where tab1.起始时间 = aa.hour and not aa.week in (7,1);
    如果想知道指定时间落在哪个班次上可用以下语句:
    select "班次" from tab1 where "起始时间" = (select to_char(指定时间,'hh24') from dual);
    如果没显示记录,则指定时间不在上班时间区间内。
      

  4.   

    最后那个语句要改成:
    select "班次" from tab1 where "起始时间" = (select to_char(指定时间,'hh24') from dual where not to_char(指定时间,'d') in (7,1)); 
    如果要考虑非固定公众假期则以上思路还得再调整。