【问题标题】:Oracle SQL Query on moving averageOracle SQL 查询移动平均线
【发布时间】:2021-06-14 15:30:31
【问题描述】:

有一个数据库包含 30 天内的网站流量。 第一个表包含用户信息,包括用户类型(user,crawler,admin)。 第二个表包含每次访问网站的时间、访问者的 ID、在网站上花费的时间(以秒为单位)。

我需要一个 Oracle SQL 查询来显示 users.user_type = 'user' 在网站上花费的 3 天移动平均时间。

表格:-

用户:-

Id Name User_type
1 Matt user
2 John user
3 Louie Admin

交通:-

user_id visited_on time_spent
1 2019-05-01 15
2 2019-05-02 20
2 2019-05-03 10

预期输出:

visited_on Average_time_spent
2019-05-01 15.0000
2019-05-02 17.5000
2019-05-03 15.0000

【问题讨论】:

    标签: oracle average aggregate-functions moving-average


    【解决方案1】:

    如果我理解得很好,下面的 select 语句会为你工作

    create table Users (Id, Name, User_type) as (
    select 1, 'Matt', 'user' from dual union all
    select 2, 'John', 'user' from dual union all
    select 3, 'Louie', 'Admin' from dual
    )
    ;
    
    create table Traffic (user_id, visited_on, time_spent) as (
    select 1, date '2019-05-01', 15 from dual union all
    select 2, date '2019-05-02', 20 from dual union all 
    select 2, date '2019-05-03', 10 from dual
    )
    ;
    
    select t.VISITED_ON
    , avg(t.TIME_SPENT)over(
        order by t.VISITED_ON
           range between interval '2' day preceding and interval '0' day following
    ) Average_time_spent
    from Users u
    join Traffic t on u.Id = t.user_id
    where u.User_type = 'user'
    ;
    
    

    【讨论】:

    • @user1402648 这不会生成 3 天移动平均线。
    【解决方案2】:

    您可以使用(如果您希望以每天为中心的 3 天平均值):

    SELECT visited_on,
           AVG( time_spent ) OVER (
             ORDER BY visited_on
             RANGE BETWEEN INTERVAL '1' DAY PRECEDING AND INTERVAL '1' DAY FOLLOWING
           ) AS average_time_spent
    FROM   traffic t
    WHERE  EXISTS (
             SELECT 1
             FROM   users u
             WHERE  u.id = t.user_id
             AND u.user_type = 'user'
           )
    ORDER BY visited_on
    

    其中,对于样本数据:

    CREATE TABLE users ( Id, Name, User_type ) AS
    SELECT 1, 'Matt',   'user' FROM DUAL UNION ALL
    SELECT 2, 'John',   'user' FROM DUAL UNION ALL
    SELECT 3, 'Louie',  'Admin' FROM DUAL;
    
    CREATE TABLE traffic ( user_id, visited_on, time_spent ) AS
    SELECT 1,   DATE '2019-05-01',  15 FROM DUAL UNION ALL
    SELECT 2,   DATE '2019-05-02',  20 FROM DUAL UNION ALL
    SELECT 2,   DATE '2019-05-03',  10 FROM DUAL;
    

    输出:

    VISITED_ON | AVERAGE_TIME_SPENT :--------- | -----------------: 19 年 5 月 1 日 | 17.5 19 年 5 月 2 日 | 15 19 年 5 月 3 日 | 15

    如果您希望移动平均线是当天和之前的 2,那么您可以更改范围:

    SELECT visited_on,
           AVG( time_spent ) OVER (
             ORDER BY visited_on
             RANGE BETWEEN INTERVAL '2' DAY PRECEDING AND INTERVAL '0' DAY FOLLOWING
           ) AS average_time_spent
    FROM   traffic t
    WHERE  EXISTS (
             SELECT 1
             FROM   users u
             WHERE  u.id = t.user_id
             AND u.user_type = 'user'
           )
    ORDER BY visited_on
    

    哪些输出:

    VISITED_ON | AVERAGE_TIME_SPENT :--------- | -----------------: 19 年 5 月 1 日 | 15 19 年 5 月 2 日 | 17.5 19 年 5 月 3 日 | 15

    db小提琴here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-24
      • 2023-03-22
      • 2017-09-01
      • 2013-12-22
      • 1970-01-01
      • 2014-12-24
      • 1970-01-01
      • 2016-07-07
      相关资源
      最近更新 更多