oracle запрос для получения почасового количества уникальных пользователей из таблицы за последние n (например, за последние 7) часов - PullRequest
0 голосов
/ 02 апреля 2020

У меня есть таблица, которая содержит столбцы данных журнала, такие как 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:00, поэтому выходные данные должны быть такими, как показано ниже, если запись присутствует, тогда уникальное число пользователей считается равным 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

Я новичок в oracle, поэтому вам нужны эксперты, пожалуйста, помогите здесь.

Ответы [ 2 ]

1 голос
/ 02 апреля 2020

Используя ваши примеры данных, что-то вроде этого может работать. См комментарии в коде.

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>
1 голос
/ 02 апреля 2020

Вам нужна какая-то таблица чисел / счетчиков. Но идея left join:

with n as (
      select 0 as n from dual union all
      select 1 as n from dual union all
      select 2 as n from dual union all
      select 3 as n from dual union all
      select 4 as n from dual
     )
select sysdate - (n + 1) * interval '1' hour,
       count(distinct t.userid)
from n left join
     test_table t
     on t.logdate >= sysdate - (n + 1) * interval '1' hour and
        t.logdate < sysdate - n * interval '1' hour
group by n
order by n;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...