按15分钟间隔对数据集进行分组

时间:2016-10-27 12:11:24

标签: oracle

我正在尝试为我们的内部公司系统建立平均数量的会话。问题是范围大约是三个月后,我想将这整组大数据分组15分钟,所以输出结果如下:

interval      sess_avg
12:00-12:15   300
12:15-12:30   350
etc..

我的查询是:

    SELECT
        TO_CHAR(sess_start_date,'YYYY-MM-DD HH24:MI:SS') time_start,
        COUNT (sess_id) how_many
                FROM
        t.sessions,
        t.users
            WHERE
        t.users.user_id         =t.sessions.sess_user_id
        AND user_type     !='X'
        AND sess_start_date>=TRUNC(ADD_MONTHS(SYSDATE,-12))
GROUP BY
        TO_CHAR(sess_start_date,'YYYY-MM-DD HH24:MI:SS')

问题在于我不知道如何开始。请帮忙。

3 个答案:

答案 0 :(得分:2)

  SELECT
        TRUNC(ADD_MONTHS(SYSDATE,-12)) + 
         floor((sess_start_date - TRUNC(ADD_MONTHS(SYSDATE,-12)))*24*4)/24/4 time_start,
        COUNT (sess_id) as how_many
FROM
        t.sessions,
        t.users
WHERE
        t.users.user_id         =t.sessions.sess_user_id
        AND user_type     !='X'
        AND sess_start_date>=TRUNC(ADD_MONTHS(SYSDATE,-12))
GROUP BY
        floor((sess_start_date - TRUNC(ADD_MONTHS(SYSDATE,-12)))*24*4)

答案 1 :(得分:1)

正如in a previous answer所述,您可以使用SSSSS格式模型来操纵日期值的时间部分。在此处应用该方法,您可以按调整后的值进行查询和分组:

SELECT
    TO_CHAR(TRUNC(sess_start_date)
            + FLOOR(TO_NUMBER(TO_CHAR(sess_start_date, 'SSSSS'))/900)/96,
        'YYYY-MM-DD HH24:MI:SS') time_start,
    COUNT (sess_id) how_many
FROM
    t.sessions,
    t.users
WHERE
    t.users.user_id = t.sessions.sess_user_id
    AND user_type !='X'
    AND sess_start_date>=TRUNC(ADD_MONTHS(SYSDATE,-12))
GROUP BY
    TRUNC(sess_start_date) + FLOOR(TO_NUMBER(TO_CHAR(sess_start_date, 'SSSSS'))/900)/96;

如果您想要时间段而不参考日期,您可以改为:

SELECT
    TO_CHAR(TO_DATE(FLOOR(TO_NUMBER(TO_CHAR(sess_start_date, 'SSSSS'))/900)*900,
      'SSSSS'),'HH24:MI') time_start,
    COUNT (sess_id) how_many
FROM
    t.sessions,
    t.users
WHERE
    t.users.user_id = t.sessions.sess_user_id
    AND user_type !='X'
    AND sess_start_date>=TRUNC(ADD_MONTHS(SYSDATE,-12))
GROUP BY
    TO_DATE(FLOOR(TO_NUMBER(TO_CHAR(sess_start_date, 'SSSSS'))/900)*900, 'SSSSS');

要获取所有日期同一时期的平均值,您可以将它们与内联视图结合使用:

SELECT
    TO_CHAR(period_start, 'HH24:MI') as period_start,
    AVG (how_many) avg_how_many
FROM (
  SELECT
      TO_DATE(FLOOR(TO_NUMBER(TO_CHAR(sess_start_date, 'SSSSS'))/900)*900,
          'SSSSS') period_start,
      TO_CHAR(TRUNC(sess_start_date)
              + FLOOR(TO_NUMBER(TO_CHAR(sess_start_date, 'SSSSS'))/900)/96,
          'YYYY-MM-DD HH24:MI:SS') time_start,
      COUNT (sess_id) how_many
  FROM
      t.sessions,
      t.users
  WHERE
      t.users.user_id = t.sessions.sess_user_id
      AND user_type !='X'
      AND sess_start_date>=TRUNC(ADD_MONTHS(SYSDATE,-12))
  GROUP BY
      TO_DATE(FLOOR(TO_NUMBER(TO_CHAR(sess_start_date, 'SSSSS'))/900)*900, 'SSSSS'),
      TRUNC(sess_start_date) + FLOOR(TO_NUMBER(TO_CHAR(sess_start_date, 'SSSSS'))/900)/96
)
GROUP BY
    period_start
ORDER BY
    period_start;

答案 2 :(得分:0)

前段时间我写了这个通用函数:

FUNCTION MakeInterval(ts IN TIMESTAMP, roundInterval IN INTERVAL DAY TO SECOND) RETURN TIMESTAMP DETERMINISTIC IS
    denom INTEGER;
BEGIN
    IF roundInterval >= INTERVAL '1' HOUR THEN
        denom := EXTRACT(HOUR FROM roundInterval);
        IF MOD(24, denom) <> 0 THEN
            RAISE VALUE_ERROR;
        END IF;
        RETURN TRUNC(ts) + TRUNC(EXTRACT(HOUR FROM ts) / denom) * denom * INTERVAL '1' HOUR;
    ELSIF roundInterval >= INTERVAL '1' MINUTE THEN
        denom := EXTRACT(MINUTE FROM roundInterval);
        IF MOD(60, denom) <> 0 THEN
            RAISE VALUE_ERROR;
        END IF;
        RETURN TRUNC(ts, 'hh') + TRUNC(EXTRACT(MINUTE FROM ts) / denom) * denom * INTERVAL '1' MINUTE;
    ELSE
        denom := EXTRACT(SECOND FROM roundInterval);                
        IF MOD(60, denom) <> 0 THEN
            RAISE VALUE_ERROR;
        END IF;
        RETURN TRUNC(ts, 'mi') + TRUNC(EXTRACT(SECOND FROM ts) / denom) * denom * INTERVAL '1' SECOND;
    END IF;
END MakeInterval;

在您的情况下,您将使用此功能,如

...
GROUP BY MakeInterval(sess_start_date, INTERVAL '15' MINUTE)

注意,如果间隔“不适合”,该函数会引发错误,例如MakeInterval(sess_start_date, INTERVAL '16' MINUTE),即有效间隔

  • INTERVAL '1' HOUR
  • INTERVAL '2' HOUR
  • INTERVAL '3' HOUR
  • INTERVAL '4' HOUR
  • INTERVAL '6' HOUR
  • INTERVAL '8' HOUR
  • INTERVAL '12' HOUR
  • INTERVAL '24' HOUR
  • INTERVAL '1' MINUTE
  • INTERVAL '2' MINUTE
  • INTERVAL '3' MINUTE
  • INTERVAL '4' MINUTE
  • INTERVAL '5' MINUTE
  • INTERVAL '6' MINUTE
  • INTERVAL '10' MINUTE
  • INTERVAL '12' MINUTE
  • INTERVAL '15' MINUTE
  • INTERVAL '20' MINUTE
  • INTERVAL '30' MINUTE