Oracle 用于查找办公室人员平均工作时间的复杂sql查询

Oracle 用于查找办公室人员平均工作时间的复杂sql查询,oracle,hibernate,Oracle,Hibernate,我需要使用基于oracle的查询检索员工的工作时间,这是基于事务表中的事务的员工的进出时间 事务表有一个日期时间字段,可用于此目的 所涉及的步骤如下: 我在某个日期找到第一笔交易,在同一日期找到最后一笔交易——这将是他在该日期的时间和超时 2将总时间计算为每个日期所有时间的平均值,超时情况也是如此 事务表如下:TransctTransId、resourceid、event、currentdate 第二个要求是找到每天执行的平均事务,这基本上是找到每天的传输次数,然后是平均数 最终答案应该是,当提

我需要使用基于oracle的查询检索员工的工作时间,这是基于事务表中的事务的员工的进出时间

事务表有一个日期时间字段,可用于此目的

所涉及的步骤如下: 我在某个日期找到第一笔交易,在同一日期找到最后一笔交易——这将是他在该日期的时间和超时 2将总时间计算为每个日期所有时间的平均值,超时情况也是如此

事务表如下:TransctTransId、resourceid、event、currentdate

第二个要求是找到每天执行的平均事务,这基本上是找到每天的传输次数,然后是平均数

最终答案应该是,当提供用户ID时,查询返回的结果是:

frequent working time(based on average): 9:43 am - 6:45 pm
average transactions performed/day = 43
如果Transctn是我的域类,我如何在oracle SQL中编写上述要求,或者更灵活地使用Hibernate编写

我有这样的想法:

select 'frequent working time: '
    ||(select rtrim(to_char(min(currentdate),'hh:mi pm')) from transctn)
    ||' - '||(select rtrim(to_char(max(currentdate),'hh:mi pm')) from transctn)
    ||', average transactions performed/day = '
    ||(select rtrim(to_char(count(distinct transid)/
        count(distinct(to_char(currentdate,'rrmmdd')))) from transctn)
from dual

首先,您的查询将来自同一个表的许多选择粘在一起,这是不高效的,并且使其难以读取。rtrim没有做任何事情,因为您已经指定了格式。您拥有的内容可以改写为:

select 'frequent working time: '|| to_char(min(currentdate),'hh:mi pm')
        ||' - '|| to_char(max(currentdate),'hh:mi pm'),
    'average transactions performed/day = '
        || to_char(count(distinct transid)
            /count(distinct to_char(currentdate,'rrmmdd')))
from transctn;
但这不是正确的平均值,也不是针对特定用户的。我认为这是一个家庭作业,按照网站通常的精神,试着给你指点,而不是完整的答案

1在某个日期查找第一笔交易,在某个日期查找最后一笔交易 同一个日期-这将是他的时间和超时的日期

你离这里不远,但你已经按日期崩溃了。要获取每个用户每天的输入和输出时间,您可以使用:

select resourceid, trunc(currentdate), min(currentdate), max(currentdate)
from transctn
group by resourceid, trunc(currentdate)
order by resourceid, trunc(currentdate);
2计算总时间in,作为每个节点上所有时间in的平均值 日期,同样适用于超时

不能直接在Oracle中平均日期;您将得到ORA-00932:不一致的数据类型:预期的数字已到达日期。实现这种效果的方法有很多种,你只需要找到一种安全的方法,将日期——或者更具体地说,时间部分——作为一个数字。例如,您可以将时间部分视为实际时间与一天开始时间之间的差值,Oracle将其作为数字返回:

select avg(min(currentdate) - trunc(currentdate)),
    avg(max(currentdate) - trunc(currentdate))
from transctn
group by trunc(currentdate);
但你不需要把分数转换成可以识别的东西。一种方法是将数字添加到任意的固定日期,然后像之前一样将时间部分提取为字符串:

select to_char(date '2000-01-01' + avg(min(currentdate) - trunc(currentdate)),
        'HH:MI pm') as avg_time_in,
    to_char(date '2000-01-01' + avg(max(currentdate) - trunc(currentdate)),
        'HH:MI pm') as avg_time_out
from transctn
group by trunc(currentdate);
这看起来很混乱,你可能会找到更好的方法。如果是家庭作业的话,我会假设你已经学会了做这类事情的方法,或者一些可以适应的方法


这仍然适用于所有资源,因此您需要添加一个过滤器以限制一个用户ID。希望这也能为您提供一些解决第二个要求的想法。

我有一些类似于选择“频繁工作时间:”| |选择rtrimto_charmincurrentdate,'hh:mi pm'的内容,从transtn| | |-“| |选择rtrimto_charmaxcurrentdate,“hh:mi pm”来自transtn | |”,平均执行事务数/天=“| |选择rtrimto_charcountdistinct transid/countdistinct to_charcurrentdate,从transtn选择“rrmmdd”来自dual