2016-10-27 15 views
1

私は社内システムに確立された平均セッション数を取得しようとしています。問題は、スコープが後方に約3ヶ月であるということであると同様に出力がされますので、私は、15分間隔でグループ大規模データのこのセット全体をしたいと思います:私のクエリがあるデータセットを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') 

問題は、どのように起動するのかわかりません。助けてください。

+2

[可能な複製?](http://stackoverflow.com/q/30920975/266304)。または[this](http://stackoverflow.com/q/21238990/266304)、状況はより複雑です。 –

答えて

1

としてはin a previous answer説明し、あなたの日付値の時刻部分を操作するためSSSSS書式モデルを使用することができます。ここでその方法を適用すると、あなたはその調整値によってクエリおよびグループすることができます:平均値を取得するには

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(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(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
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) 
0

いくつかの時間前、私はこの一般的な機能を書いた:

あなたは

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

ノートのように、この機能を使用することになり、あなたの場合は

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; 

間隔は、例えば、「合わない」場合、関数はエラーを発生させます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 '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
関連する問題