我正在尝试为我们的内部公司系统建立平均数量的会话。问题是范围大约是三个月后,我想将这整组大数据分组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')
问题在于我不知道如何开始。请帮忙。
答案 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