2010-11-26 6 views
3

私は、シフト管理に応じて、2日間にわたって開かれるビジネスのために、日時ベースのトランザクションレポートを作成しようとしています。DATETIMEの範囲で「グループ化」する方法は?

ユーザーはdatetimeの範囲(毎月、毎日、毎週、自由...)を選択できます。実装したクエリはstartDateTimeとEndDateTimeを取得し、すべてのトランザクションを合計で1日ごとに返します。

I.E.

DateTime  Total Sales 
--------------------------- 
10/15/2010  $2,300.38 
10/16/2010  $1,780.00 
10/17/2010  $4,200.22 
10/20/2010  $900.66 

私の問題は、ビジネスのシフトがsettedであれば、例えば、次の日の02.00 AMに05.00 AMから、02.00 AMに真夜中から行われたすべてのトランザクションは、次の日にグループ化されるということです...など...合計は壊れています。 ビジネスがこのようなシフトを抱えている場合、そのシフトに基づいたレポートが必要ですが、コードのパッチを適用しないと(JavaのOracleネイティブ問合せを使用しています)、リクエストされたレポートを取得できません。

Oracle以外のものを使用して、これらの一連のトランザクションを日時の範囲でグループ化するスマートな方法があるのだろうかと思います。ここで

は、7月のため、クエリを行く:

SELECT Q1.dateFormat, NVL(Q1.sales, 0) 
    FROM (
     SELECT to_date(to_char(tx.datetimeGMT +1/24 , 'mm-dd-yyyy'), 'mm-dd-yyyy') AS dateFormat      
       , NVL(SUM(tx.amount),0) AS sales 
      FROM Transaction tx 
      WHERE tx.datetimeGMT > to_date('20100801 08:59:59', 'yyyymmdd hh24:mi:ss') +1/24 
       AND tx.datetimeGMT < to_date('20100901 09:00:00', 'yyyymmdd hh24:mi:ss') + 1/24 
      GROUP BY to_date(to_char(tx.datetimeGMT +1/24 , 'mm-dd-yyyy'), 'mm-dd-yyyy') 
    ) Q1 
    ORDER BY 1 DESC 

答えて

3

は彼らに見てとることで、私は書くことができ、あなたの答えありがとうございました

SELECT CASE 
    WHEN EXTRACT(HOUR FROM TX.DATETIME) >= 5 THEN TO_CHAR(TX.DATETIME,'DD-MM-YYYY') 
    WHEN EXTRACT(HOUR FROM TX.DATETIME) BETWEEN 0 AND 2 THEN TO_CHAR(TX.DATETIME-1,'DD-MM-YYYY') 
    WHEN EXTRACT(hour from tx.datetime) between 2 and 5 THEN to_char(TX.DATETIME-1,'DD-MM-YYYY') 
    END AS age, 
    NVL(SUM(tx.amount),0) AS sales 
FROM TRANSACTION TX 
WHERE tx.datetime > to_date('20100801 08:59:59', 'yyyymmdd hh24:mi:ss') 
    AND TX.DATETIME < TO_DATE('20100901 09:00:00', 'yyyymmdd hh24:mi:ss') 
GROUP BY CASE 
    WHEN EXTRACT(HOUR FROM TX.DATETIME) >= 5 THEN TO_CHAR(TX.DATETIME,'DD-MM-YYYY') 
    WHEN EXTRACT(HOUR FROM TX.DATETIME) BETWEEN 0 AND 2 THEN TO_CHAR(TX.DATETIME-1,'DD-MM-YYYY') 
    WHEN EXTRACT(hour from tx.datetime) between 2 and 5 THEN to_char(TX.DATETIME-1,'DD-MM-YYYY') 
    END 
ORDER BY 1 
0

群には、日付範囲によって、あなたはそれによって、カラムサブクエリに値、およびグループに、この範囲を持っている必要がありますあなたの質問に。明らかに、この列値内のこの日付範囲はVARCHAR型になります。

+0

これは必ずしもvarchar値ではありません。 – Donnie

0

1日の最初のシフトが08:00に開始し、その同じ日の最後のシフトが翌日に07:59に終了した場合は、このような方法を使用してトランザクションをシフト日ごとにグループ化できます。

select trunc(trans_date - interval '8' hour) as shift_date 
     ,sum(amount) 
    from transactions 
group 
    by trunc(trans_date - interval '8' hour) 
order 
    by shift_date desc; 
0

あなたは(それが実行されている場合でもわからない、ちょうど私の頭の外に)このアプローチを試すことができます。

select 
trans_date, 
trans_shift, 
aggregates(whatever) 
from (
    select 
    -- we want to group by normalized transaction date, 
    -- not by real transaction date 
    normalized_trans_date, 
    -- get the shift to group by 
    case 
     when trans_date between trunc(normalized_trans_date) + shift_1_start_offset and 
           trunc(normalized_trans_date) + shift_1_end_offset then 
     1 
     when trans_date between trunc(normalized_trans_date) + shift_2_start_offset and 
           trunc(normalized_trans_date) + shift_2_end_offset then 
     2 
     ... 
     when trans_date between trunc(normalized_trans_date) + shift_N_start_offset and 
           trunc(normalized_trans_date) + shift_N_end_offset then 
     N 
    end trans_shift, 
    whatever 
    from (
     select 
     -- get a normalized transaction date: if date is before 1st shift 
     -- it belongs to the day before 
     case 
      when trans_date - trunc(trans_date) < shift_1_start_offset then 
      trans_date - 1 
      else 
      trans_date 
     end normalized_trans_date, 
     t.* 
     from 
     transactions t 
    ) 
) 
group by trans_date, trans_shift 
関連する問題