Sql oracle查询以从表中获取过去n(例如过去7)小时的每小时唯一用户数

Sql oracle查询以从表中获取过去n(例如过去7)小时的每小时唯一用户数,sql,oracle,Sql,Oracle,我有一个表,其中包含像userid和log_date这样的日志数据列,我想检索过去7小时的唯一用户计数 test_table ---------------- userid logdate 1 04/02/2020 02:12:00 PM 1 04/02/2020 02:00:00 PM 2 04/02/2020 01:50:00 PM 1 04/02/2020 01:10:00 PM 2 04/02/2020 01:11:00 PM 3

我有一个表,其中包含像userid和log_date这样的日志数据列,我想检索过去7小时的唯一用户计数

test_table
----------------
userid logdate
1      04/02/2020 02:12:00 PM 
1      04/02/2020 02:00:00 PM
2      04/02/2020 01:50:00 PM
1      04/02/2020 01:10:00 PM
2      04/02/2020 01:11:00 PM
3      04/02/2020 01:12:00 PM
1      04/02/2020 10:12:00 AM
4      04/02/2020 10:14:00 AM
假设sysdate为04/02/2020 02:12:14 PM,则输出应如下所示:如果记录存在,则唯一用户计数为0

unique_user_count time
2                 NOW(04/02/2020 02:12:14 PM)
3                 04/02/2020 01:12:14 PM
0                 04/02/2020 12:12:14 PM
2                 04/02/2020 11:12:14 AM
0                 04/02/2020 10:12:14 AM
0                 04/02/2020 09:12:14 AM
0                 04/02/2020 08:12:14 AM

我是甲骨文新手,所以这里需要专家帮助。

您需要某种数字/理货表。但这个想法是一个左连接:


你需要某种数字/理货表。但这个想法是一个左连接:


使用示例数据,类似的方法可能会奏效。请参阅代码中的注释

SQL> with
  2  right_now (datum) as
  3    -- it is used instead of SYSDATE, because of sample data
  4    (select to_date('02.04.2020 14:12', 'dd.mm.yyyy hh24:Mi') from dual),
  5  test (userid, logdate) as
  6    (select 1, to_date('02.04.2020 14:12', 'dd.mm.yyyy hh24:mi') from dual union all
  7     select 1, to_date('02.04.2020 14:00', 'dd.mm.yyyy hh24:mi') from dual union all
  8     select 2, to_date('02.04.2020 13:50', 'dd.mm.yyyy hh24:mi') from dual union all
  9     select 1, to_date('02.04.2020 13:10', 'dd.mm.yyyy hh24:mi') from dual union all
 10     select 2, to_date('02.04.2020 13:11', 'dd.mm.yyyy hh24:mi') from dual union all
 11     select 3, to_date('02.04.2020 13:12', 'dd.mm.yyyy hh24:mi') from dual union all
 12     select 1, to_date('02.04.2020 10:12', 'dd.mm.yyyy hh24:mi') from dual union all
 13     select 4, to_date('02.04.2020 10:14', 'dd.mm.yyyy hh24:mi') from dual
 14    ),
 15  calendar as
 16    -- in real situation, you'd use SYSDATE instead of DATUM and DUAL instead of RIGHT_NOW
 17    (select r.datum - (level - 1) / 24 datum,
 18        lag(r.datum - (level - 1) / 24) over (order by level desc) prev_datum
 19     from right_now r
 20     connect by level <= 8
 21    )
 22  select count(distinct t.userid) distinct_users,
 23         to_char(c.prev_datum, 'hh24:mi') ||' - '||
 24         to_char(c.datum     , 'hh24:mi') period
 25  from calendar c left join test t on t.logdate between c.prev_datum and c.datum
 26  where c.prev_datum is not null
 27  group by to_char(c.prev_datum, 'hh24:mi') ||' - '||
 28           to_char(c.datum     , 'hh24:mi')
 29  order by 2;

DISTINCT_USERS PERIOD
-------------- -------------
             0 07:12 - 08:12
             0 08:12 - 09:12
             1 09:12 - 10:12
             2 10:12 - 11:12
             0 11:12 - 12:12
             3 12:12 - 13:12
             3 13:12 - 14:12

7 rows selected.

SQL>

使用示例数据,类似的方法可能会奏效。请参阅代码中的注释

SQL> with
  2  right_now (datum) as
  3    -- it is used instead of SYSDATE, because of sample data
  4    (select to_date('02.04.2020 14:12', 'dd.mm.yyyy hh24:Mi') from dual),
  5  test (userid, logdate) as
  6    (select 1, to_date('02.04.2020 14:12', 'dd.mm.yyyy hh24:mi') from dual union all
  7     select 1, to_date('02.04.2020 14:00', 'dd.mm.yyyy hh24:mi') from dual union all
  8     select 2, to_date('02.04.2020 13:50', 'dd.mm.yyyy hh24:mi') from dual union all
  9     select 1, to_date('02.04.2020 13:10', 'dd.mm.yyyy hh24:mi') from dual union all
 10     select 2, to_date('02.04.2020 13:11', 'dd.mm.yyyy hh24:mi') from dual union all
 11     select 3, to_date('02.04.2020 13:12', 'dd.mm.yyyy hh24:mi') from dual union all
 12     select 1, to_date('02.04.2020 10:12', 'dd.mm.yyyy hh24:mi') from dual union all
 13     select 4, to_date('02.04.2020 10:14', 'dd.mm.yyyy hh24:mi') from dual
 14    ),
 15  calendar as
 16    -- in real situation, you'd use SYSDATE instead of DATUM and DUAL instead of RIGHT_NOW
 17    (select r.datum - (level - 1) / 24 datum,
 18        lag(r.datum - (level - 1) / 24) over (order by level desc) prev_datum
 19     from right_now r
 20     connect by level <= 8
 21    )
 22  select count(distinct t.userid) distinct_users,
 23         to_char(c.prev_datum, 'hh24:mi') ||' - '||
 24         to_char(c.datum     , 'hh24:mi') period
 25  from calendar c left join test t on t.logdate between c.prev_datum and c.datum
 26  where c.prev_datum is not null
 27  group by to_char(c.prev_datum, 'hh24:mi') ||' - '||
 28           to_char(c.datum     , 'hh24:mi')
 29  order by 2;

DISTINCT_USERS PERIOD
-------------- -------------
             0 07:12 - 08:12
             0 08:12 - 09:12
             1 09:12 - 10:12
             2 10:12 - 11:12
             0 11:12 - 12:12
             3 12:12 - 13:12
             3 13:12 - 14:12

7 rows selected.

SQL>

非常感谢,这正是我想要的,非常感谢。非常感谢,这正是我想要的,非常感谢。