oracle 获取SQL或SSRS中的平均时间

9bfwbjaz  于 2023-10-16  发布在  Oracle
关注(0)|答案(2)|浏览(82)

我在做一个考勤系统。在代码中:

SELECT
c.gregorian_date,
c.WORKING_DAY,
c.notes,
a.am_empno AS emp_no,
t.emp_name,
a.Time_In,
a.Time_Out,
a.am_att_status,
t.team_name,
t.line_manager,
(SELECT COUNT(a2.Time_In)
 FROM pp_emp_att_mst_v a2
 WHERE a2.am_empno = a.am_empno
   AND a2.Time_In >= '09:15:00'
   AND a2.am_date BETWEEN TRUNC(SYSDATE, 'mm') AND TRUNC(SYSDATE)
) AS Time_In_MTD,

**-- Here I want AVG(a.Time_In)**

FROM
dim_calendar c
JOIN pp_emp_att_mst_v a ON c.gregorian_date = a.am_date AND a.am_date = TRUNC(SYSDATE)
JOIN team_names t ON a.am_empno = t.EMP_NO
WHERE
c.gregorian_date = TRUNC(SYSDATE)
AND a.Time_In >= '09:15:00'
AND c.gregorian_date BETWEEN TRUNC(SYSDATE, 'mm') AND TRUNC(SYSDATE)

我想得到平均时间。
我也在SSRS报告中使用这个查询,所以如果有一种方法可以在SSRS报告中获得平均时间,请分享。

vlju58qv

vlju58qv1#

您需要将时间转换为数值,然后可以对其进行平均并将其转换回时间。假设你想要一个相似的平均值为每个员工为当前月份,那么你可以使用:用途:

SELECT c.gregorian_date,
       a.am_empno AS emp_no,
       t.emp_name,
       a.Time_In,
       ( SELECT TO_CHAR(
                  TRUNC(SYSDATE)
                  + AVG(
                    TO_DATE(a2.Time_In, 'HH24:MI:SS')
                    - TO_DATE('00:00:00', 'HH24:MI:SS')
                  ),
                  'HH24:MI:SS'
                )
         FROM   pp_emp_att_mst_v a2
         WHERE  a2.am_empno = a.am_empno
         AND    a2.am_date BETWEEN TRUNC(SYSDATE, 'mm') AND TRUNC(SYSDATE)
       ) AS avg_time_in_for_current_month
FROM   dim_calendar c
       JOIN pp_emp_att_mst_v a
       ON c.gregorian_date = a.am_date AND a.am_date = TRUNC(SYSDATE)
       JOIN team_names t
       ON a.am_empno = t.EMP_NO
WHERE  c.gregorian_date = TRUNC(SYSDATE)
AND    a.Time_In >= '09:15:00'
AND    c.gregorian_date BETWEEN TRUNC(SYSDATE, 'mm') AND TRUNC(SYSDATE)
kx7yvsdv

kx7yvsdv2#

time_in列的数据类型是什么?根据你发布的内容,看起来像一个字符串:
AND a.Time_In >= '09:15:00'
如果确实如此,请考虑将日期(和时间)值存储在datetimestamp数据类型列中;如果它是varchar2,你可以有,例如。45:82:92存储在那里,这不是一个有效的时间值。如果是例如。date数据类型,数据库不会让你将这样的垃圾存储到列中。
无论如何:假设这真的是一个字符串,然后将其转换为时间戳(以便提取函数完成其工作),将小时乘以60(以便您获得分钟)并添加分钟本身。计算平均分钟数,并将该数字转换回小时:分钟格式。
样本数据:

SQL>  WITH
  2     test (id, time_in)
  3     AS
  4        (SELECT 1, '08:44' FROM DUAL
  5         UNION ALL
  6         SELECT 2, '08:28' FROM DUAL
  7         UNION ALL
  8         SELECT 3, '08:52' FROM DUAL
  9         UNION ALL
 10         SELECT 4, '08:59' FROM DUAL
 11         UNION ALL
 12         SELECT 5, '08:35' FROM DUAL),

查询方式:

13     temp
 14     AS
 15        (SELECT AVG (
 16                     EXTRACT (HOUR FROM TO_TIMESTAMP (time_in, 'hh24:mi')) * 60
 17                   + EXTRACT (MINUTE FROM TO_TIMESTAMP (time_in, 'hh24:mi'))) AS avg_num
 18           FROM test)
 19  SELECT    LPAD (TRUNC (avg_num / 60), 2, '0')
 20         || ':'
 21         || ROUND ((avg_num / 60 - TRUNC (avg_num / 60)) * 60) avg_time_in
 22    FROM temp;

AVG_TIME_IN
-------------------------------------------
08:44

是这样吗?

SQL> select (44 + 28 + 52 + 59 + 35) / 5 as avg_minutes from dual;

AVG_MINUTES
-----------
       43,6     --> rounded, it makes 44 minutes

如果time_in存储在date数据类型列中,您将执行类似的操作:首先将日期转换为时间戳,其余部分如上例所示。
样本数据:

SQL> WITH
  2     test (id, time_in)
  3     AS
  4        (SELECT 1, TO_DATE ('08.09.2023 08:44', 'dd.mm.yyyy hh24:mi') FROM DUAL
  5         UNION ALL
  6         SELECT 2, TO_DATE ('09.09.2023 08:28', 'dd.mm.yyyy hh24:mi') FROM DUAL
  7         UNION ALL
  8         SELECT 3, TO_DATE ('10.09.2023 08:52', 'dd.mm.yyyy hh24:mi') FROM DUAL
  9         UNION ALL
 10         SELECT 4, TO_DATE ('11.09.2023 08:59', 'dd.mm.yyyy hh24:mi') FROM DUAL
 11         UNION ALL
 12         SELECT 5, TO_DATE ('12.09.2023 08:35', 'dd.mm.yyyy hh24:mi') FROM DUAL),

查询方式:

13     temp
 14     AS
 15        (SELECT AVG (
 16                     EXTRACT (HOUR FROM CAST (time_in AS TIMESTAMP)) * 60
 17                   + EXTRACT (MINUTE FROM CAST (time_in AS TIMESTAMP))) AS avg_num
 18           FROM test)
 19  SELECT    LPAD (TRUNC (avg_num / 60), 2, '0')
 20         || ':'
 21         || ROUND ((avg_num / 60 - TRUNC (avg_num / 60)) * 60) avg_time_in
 22    FROM temp;

AVG_TIME_IN
-------------------------------------------
08:44

相关问题