oracle按小时查询显示数据

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了oracle按小时查询显示数据相关的知识,希望对你有一定的参考价值。

按小时查询,比如说2013-4-18 11:06 到2013-4-18 12:06 有多少条数据,是按小时显示的,2013-4-18 11:06 到2013-4-18 12:06时间段之间的数据,我在mysql里找到了方法,但oracle不行,查出来的时间类似于图,比如说2011-03-15 13点之内就只显示它,而13点之内不止一条数据 ,我不是要查他的字段,我只是查13点内数据的条数

        可以使用to_char()、concat()等函数实现查询前一小时、前一天、前一个月或者前一年的数据。

1、查询一小时

    1)to_char(sysdate,\'yyyy-mm-dd \')将系统当前时间转换为字符类型,仅取出年月日

    2)|| 字符串连接符

    3)to_char(sysdate,\'hh24\')-1取出系统当前时间的小时部分,hh24小时是24进制的

    4)concat是字符串连接函数

select concat(to_char(sysdate,\'yyyy-mm-dd \')||(to_char(sysdate,\'hh24\')-1),\':00:00\') start_time,concat(to_char(sysdate,\'yyyy-mm-dd hh24\'),\':00:00\') end_time from dual

2、查询前一天

    

  1)to_char(sysdate,\'yyyy-mm-dd \')将系统当前时间转换为字符类型,仅取出年月日

    2)|| 字符串连接符

 select to_char(sysdate-1,\'yyyy-mm-dd \')||\'00:00:00\' start_time,to_char(sysdate-1,\'yyyy-mm-dd \')||\'23:59:59\' end_time  from dual

3、查询前一个月

 1)to_char(sysdate,\'yyyy-mm-dd \')将系统当前时间转换为字符类型,仅取出年月日

    2)|| 字符串连接符

    3)add_months(sysdate,-1)取出系统当前时间月部分,然后-1

    4)concat是字符串连接函数

select concat(to_char(sysdate,\'yyyy\')||to_char(add_months(sysdate,-1), \'-MM-\'),\'01 00:00:00\')start_time,   
   concat(to_char(sysdate,\'yyyy\')||to_char(add_months(sysdate,-1), \'-MM-\')||to_char(LAST_DAY(sysdate),\'dd \'),\'23:59:59\') end_time     from dual

4、查询前一年

    1) extract(year from sysdate) 从系统日期从取出年部分

       2)|| 字符串连接符

    3)to_char(LAST_DAY(sysdate),\'dd \')取出系统日期中的最后一天

4)concat是字符串连接函数

 select extract(year from sysdate)-1||\'-01-01 00:00:00\' start_time,concat(extract(year from sysdate)-1||\'-12-\'||to_char(LAST_DAY(sysdate),\'dd \'),\'23:59:59\') end_time   from dual
参考技术A select count(时间)
from table
where 时间 between to_date('2013-4-18 11:06','YYYY-MM-DD HH24:MI:SS')
and to_date('2013-4-18 12:06','YYYY-MM-DD HH24:MI:SS')追问

我不是只查这一个时间段的哦·····我是要选择个时间段,时间段是以天计的,在这一天内哪些小时有数据让他就统计下,应该会用到group by的,也就是比如说今天1点有5条数据 2点有4条数据 3点有6条数据 。。。。。依次类推

追答

select trunc(时间,'HH24') 时段,count(*)
from table
where trunc(时间)=to_date(2011-3-15','YYYY-MM-DD')
group by trunc(时间,'HH24')
;

trunc函数可以截到你想要的任何时段需求

追问

我给出一个时间,时间从年给到小时比如 2012-3-15 08 我要查在这个小时内的条数要怎么查呢,也就是从8点到9点前的 ,但我只给8点那个时间,所以只能根据8点那个时间查,到实施的时候肯定不是只8点那个死数据撒,是变动的

追答

select count(*)
from table
where trunc(时间)=to_date(2012-3-15 8:00:00','YYYY-MM-DD hh24:MI:SS')

追问

不得行哦···查出来是0

追答

select count(*)
from table
where trunc(时间,'HH24')=to_date(2012-3-15 8:00:00','YYYY-MM-DD hh24:MI:SS')

不好意思,写错了

本回答被提问者采纳

并发用户报告

【中文标题】并发用户报告【英文标题】:Concurrent User Report 【发布时间】:2013-10-28 15:53:38 【问题描述】:

我在 Oracle 中有一个跟踪用户登录和注销/超时的表。我正在进行选择查询,以按小时显示过去 7 天的并发用户数。我有一个基本查询,但它没有正确计算会话超过午夜的用户。

关于数据/我的查询的一些信息:

Lo​​gintracking 保存所有用户登录操作,例如登录/注销/超时操作。每个操作都位于单独的行中。 Attemptdate 是动作发生的时间 Attemptresult7 是登录操作的结果(LOGIN/LOGOUT/TIMEOUT) Maxsessionuid 是用户会话 id,可用于将登录与注销/超时联系起来。 我正在使用左外自连接来匹配登录和基于会话 ID 的注销。由于用户可能仍处于登录状态,因此我将空注销日期替换为 sysdate。 我按年/月/日对数据进行分组,并删除用户可能以不同方式登录两次的所有记录。在此报告中,同一用户登录 10 次仅被视为 1 个并发用户。 (这部分也没有真正起作用,因为我的不同之处在于登录和注销时间,会话之间可能会有所不同。我真的需要为同一用户组合重叠会话......) 我通过查看从 0 到 23 的每小时是否介于他们的登录和注销之间来计算并发用户的数量(这当然不适用于跨天的会话)

--到目前为止我的 Oracle 查询:

Select Lyear,
        Lmonth,
        Lday,
        Sum(Case When 0 Between Lhour And Ohour Then 1 Else 0 End) H00,
        Sum(CASE WHEN 1 between LHour and OHour Then 1 Else 0 End) H01,
        Sum(CASE WHEN 2 between LHour and OHour Then 1 Else 0 End) H02,
        Sum(Case When 3 Between Lhour And Ohour Then 1 Else 0 End) H03,
        Sum(CASE WHEN 4 between LHour and OHour Then 1 Else 0 End) H04,
        Sum(CASE WHEN 5 between LHour and OHour Then 1 Else 0 End) H05,
        Sum(CASE WHEN 6 between LHour and OHour Then 1 Else 0 End) H06,
        Sum(CASE WHEN 7 between LHour and OHour Then 1 Else 0 End) H07,
        Sum(CASE WHEN 8 between LHour and OHour Then 1 Else 0 End) H08,
        Sum(Case When 9 Between Lhour And Ohour Then 1 Else 0 End) H09,
        Sum(CASE WHEN 10 between LHour and OHour Then 1 Else 0 End) H10,
        Sum(CASE WHEN 11 between LHour and OHour Then 1 Else 0 End) H11,
        Sum(CASE WHEN 12 between LHour and OHour Then 1 Else 0 End) H12,
        Sum(CASE WHEN 13 between LHour and OHour Then 1 Else 0 End) H13,
        Sum(CASE WHEN 14 between LHour and OHour Then 1 Else 0 End) H14,
        Sum(CASE WHEN 15 between LHour and OHour Then 1 Else 0 End) H15,
        Sum(Case When 16 Between Lhour And Ohour Then 1 Else 0 End) H16,
        Sum(Case When 17 Between Lhour And Ohour Then 1 Else 0 End) H17,
        Sum(Case When 18 Between Lhour And Ohour Then 1 Else 0 End) H18,
        Sum(CASE WHEN 19 between LHour and OHour Then 1 Else 0 End) H19,
        Sum(Case When 20 Between Lhour And Ohour Then 1 Else 0 End) H20,
        Sum(Case When 21 Between Lhour And Ohour Then 1 Else 0 End) H21,
        Sum(CASE WHEN 22 between LHour and OHour Then 1 Else 0 End) H22,
        Sum(Case When 23 Between Lhour And Ohour Then 1 Else 0 End) H23
From (    
Select Distinct L1.Userid,
         Extract(Year From L1.Attemptdate) Lyear,  
         Extract(Month From L1.Attemptdate) Lmonth, 
         Extract(Day From L1.Attemptdate) Lday,
    --You can't extract HOUR from a date, must be a timestamp
         Extract(Hour From Cast(L1.Attemptdate As Timestamp)) As Lhour, 
         Extract(Hour From Cast(NVL(L2.Attemptdate,SYSDATE) As Timestamp)) As OHour
  From Maximo.Logintracking L1
        LEFT OUTER JOIN Maximo.Logintracking L2 On
          L1.Maxsessionuid = L2.Maxsessionuid
  Where L1.Attemptresult7 = 'LOGIN' And L2.Attemptresult7 != 'LOGIN'
        And L1.Attemptdate > Trunc( Sysdate)-7
        And L2.Attemptdate > Trunc(Sysdate)-7) Sessions
Group By Lyear, Lmonth, Lday    
ORDER By LYear, LMonth, LDay

查询不必像现在一样保持不变。但最终结果应该是我按小时查看了 x 天的并发用户数。

相关:How to count the number of concurrent users using time interval data?

【问题讨论】:

【参考方案1】:

在此过程中,我写得非常简单整洁的查询变成了这个怪物(似乎有效,所以至少有一件好事):

CREATE TABLE logintracking (
  userid NUMBER,
  maxsessionuid NUMBER,
  Attemptdate DATE,
  attemptresult7 VARCHAR2(20)
);

INSERT INTO logintracking VALUES (1, 100, TO_DATE('27-10-2013 10:00:00', 'DD-MM-YYYY HH24:MI:SS'), 'LOGIN');
INSERT INTO logintracking VALUES (1, 100, TO_DATE('27-10-2013 12:00:00', 'DD-MM-YYYY HH24:MI:SS'), 'LOGOUT');

INSERT INTO logintracking VALUES (1, 101, TO_DATE('27-10-2013 11:00:00', 'DD-MM-YYYY HH24:MI:SS'), 'LOGIN');
INSERT INTO logintracking VALUES (1, 101, TO_DATE('27-10-2013 15:00:00', 'DD-MM-YYYY HH24:MI:SS'), 'LOGOUT');

INSERT INTO logintracking VALUES (1, 102, TO_DATE('27-10-2013 23:00:00', 'DD-MM-YYYY HH24:MI:SS'), 'LOGIN');
INSERT INTO logintracking VALUES (1, 102, TO_DATE('28-10-2013 02:00:00', 'DD-MM-YYYY HH24:MI:SS'), 'LOGOUT');

INSERT INTO logintracking VALUES (1, 103, TO_DATE('27-10-2013 20:00:00', 'DD-MM-YYYY HH24:MI:SS'), 'LOGIN');
INSERT INTO logintracking VALUES (1, 103, TO_DATE('28-10-2013 01:00:00', 'DD-MM-YYYY HH24:MI:SS'), 'LOGOUT');

INSERT INTO logintracking VALUES (2, 104, TO_DATE('27-10-2013 23:00:00', 'DD-MM-YYYY HH24:MI:SS'), 'LOGIN');
INSERT INTO logintracking VALUES (2, 104, TO_DATE('28-10-2013 02:00:00', 'DD-MM-YYYY HH24:MI:SS'), 'LOGOUT');

COMMIT;

WITH
  hours_of_last_7_days AS (
    SELECT TRUNC(SYSDATE, 'HH24') - numtodsinterval(level, 'HOUR') AS hour_val
      FROM dual
    CONNECT BY level <= 7 * 24
  )
SELECT
    lyear,
    lmonth,
    lday,
    SUM(DECODE(lhour, 0, 1, 0)) AS H00,
    SUM(DECODE(lhour, 1, 1, 0)) AS H01,
    SUM(DECODE(lhour, 2, 1, 0)) AS H02,
    SUM(DECODE(lhour, 3, 1, 0)) AS H03,
    SUM(DECODE(lhour, 4, 1, 0)) AS H04,
    SUM(DECODE(lhour, 5, 1, 0)) AS H05,
    SUM(DECODE(lhour, 6, 1, 0)) AS H06,
    SUM(DECODE(lhour, 7, 1, 0)) AS H07,
    SUM(DECODE(lhour, 8, 1, 0)) AS H08,
    SUM(DECODE(lhour, 9, 1, 0)) AS H09,
    SUM(DECODE(lhour, 10, 1, 0)) AS H10,
    SUM(DECODE(lhour, 11, 1, 0)) AS H11,
    SUM(DECODE(lhour, 12, 1, 0)) AS H12,
    SUM(DECODE(lhour, 13, 1, 0)) AS H13,
    SUM(DECODE(lhour, 14, 1, 0)) AS H14,
    SUM(DECODE(lhour, 15, 1, 0)) AS H15,
    SUM(DECODE(lhour, 16, 1, 0)) AS H16,
    SUM(DECODE(lhour, 17, 1, 0)) AS H17,
    SUM(DECODE(lhour, 18, 1, 0)) AS H18,
    SUM(DECODE(lhour, 19, 1, 0)) AS H19,
    SUM(DECODE(lhour, 20, 1, 0)) AS H20,
    SUM(DECODE(lhour, 21, 1, 0)) AS H21,
    SUM(DECODE(lhour, 22, 1, 0)) AS H22,
    SUM(DECODE(lhour, 23, 1, 0)) AS H23
  FROM (
    SELECT
      DISTINCT
          sessions.userid,
          EXTRACT(YEAR FROM hour_val) AS lyear,
          EXTRACT(MONTH FROM hour_val) AS lmonth,
          EXTRACT(DAY FROM hour_val) AS lday,
          EXTRACT(HOUR FROM CAST(hour_val AS TIMESTAMP)) AS lhour
        FROM (
            SELECT start_lt.userid, start_lt.attemptdate AS login_date, NVL(end_lt.attemptdate, sysdate) AS logout_date
              FROM
                logintracking start_lt
                  LEFT OUTER JOIN logintracking end_lt  ON (start_lt.maxsessionuid = end_lt.maxsessionuid AND start_lt.attemptresult7 <> end_lt.attemptresult7)
            WHERE
              start_lt.attemptresult7 = 'LOGIN'
              AND start_lt.attemptdate > Trunc(SYSDATE) - 8
          ) sessions
          JOIN hours_of_last_7_days hd ON (hd.hour_val BETWEEN trunc(sessions.login_date,'HH24') AND trunc(sessions.logout_date,'HH24'))
  )
GROUP BY lyear, lmonth, lday
ORDER BY lyear, lmonth, lday
;

输出:

 LYEAR LMONTH LDAY H00 H01 H02 H03 H04 H05 H06 H07 H08 H09 H10 H11 H12 H13 H14 H15 H16 H17 H18 H19 H20 H21 H22 H23
---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
      2013 10 27 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 1 1 1 2
      2013 10 28 2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

【讨论】:

非常感谢。我将 Hours_Of_Last_7_days 更改为使用 TRUNC(SYSDATE,'DDD'),我还将内部选择更改为使用 Trunc(SYSDATE,'DDD') - 8 而不是 -7,因为它会切断在午夜之前开始的登录会话第一天,但​​在午夜后结束。

以上是关于oracle按小时查询显示数据的主要内容,如果未能解决你的问题,请参考以下文章

Oracle SQL count() 每小时

oracle中怎么按每小时分组。数据如下:

如何高效地按小时查询大型数据库?

Oracle 取过去一个小时每分钟的数据应该如何写sql?

oracle怎么按个数分组

oracle求查询连续三天的数据