2012-02-17 3 views
0

私は、oracleベースのクエリを使用して、従業員の勤務時間を取得する必要があります。トランザクションテーブル複雑なSQLのクエリオフィスの人の平均勤務時間を見つけるために

トランザクションテーブルには、この目的で使用できる日時フィールドがあります。 1)日付の最初のトランザクションと同じ日付の最後のトランザクションを見つける - その日付の彼の時間とタイムアウト 2)全体的な時間 - 次のように各日付のすべての時間インの平均として、同様にタイムアウトのため

トランザクション・テーブルがあるか:transctn(transid, resourceid, event, currentdate)

第二の要件は、毎日行わ平均取引を見つけることで、基本的になります毎日のトランジションの数を求め、その平均を求めます。

frequent working time(based on average): 9:43 am - 6:45 pm 
average transactions performed/day = 43 

私はTransctnが私のドメインクラスであれば休止状態使用して、よりスマートにOracleのSQLで上記の要件を記述したりするにはどうすればよい:リターン結果がユーザーIDがクエリを提供する

最終的な答えをする必要があり、

私はこのようなものがあります:

select 'frequent working time: ' 
    ||(select rtrim(to_char(min(currentdate),'hh:mi pm')) from transctn) 
    ||' - '||(select rtrim(to_char(max(currentdate),'hh:mi pm')) from transctn) 
    ||', average transactions performed/day = ' 
    ||(select rtrim(to_char(count(distinct transid)/ 
     count(distinct(to_char(currentdate,'rrmmdd')))) from transctn) 
from dual 
+0

私はこのようなSELectの頻繁な作業時間を持っています: '||(transtnからのrtrim(to_char(mind)、' hh:mi pm ')の選択) ||' - '||(transtnからのtotchar(to_char(max(currentdate)、' hh:mi pm ')))from ||'、平均取引実行日/ ' ||(選択rtrim(to_char(count(distinct) transid)/ count(別名(to_char(currentdate、 'rrmmdd'))))from transctn)デュアルから –

答えて

1

まず、クエリが同じテーブルから選択の多くは効率的ではないとする、貼り合わせ、及びMAKたが必要以上に読みにくいです。 rtrimは既にフォーマットを指示しているので何もしていません。あなたが持っているものは次のように書き直すことができます:

select 'frequent working time: '|| to_char(min(currentdate),'hh:mi pm') 
     ||' - '|| to_char(max(currentdate),'hh:mi pm'), 
    'average transactions performed/day = ' 
     || to_char(count(distinct transid) 
      /count(distinct to_char(currentdate,'rrmmdd'))) 
from transctn; 

これは正しくは平均化されておらず、特定のユーザー向けではありません。私はこれが宿題であると仮定して、サイトの通常の精神の中で、完全な答えではなくポインタを与えるようにします...

1)日付と最後のトランザクション 同じ日に - その日付

のための彼の時間とタイムアウトになりますが、ここで遠くないですが、あなたは日付によって破壊しています。時間で、すべてのユーザーのためのタイムアウトを取得するには、それぞれの日のために、あなたが使用できます。

select resourceid, trunc(currentdate), min(currentdate), max(currentdate) 
from transctn 
group by resourceid, trunc(currentdate) 
order by resourceid, trunc(currentdate); 

2)各 上のすべての時間インの平均として全体的な時間を-で計算します日付も同様にタイムアウトになります

Oracleでは直接日付を平均化することはできません。 ORA-00932: inconsistent datatypes: expected NUMBER got DATEを取得します。効果を達成するにはさまざまな方法があります。日付を扱う安全な方法、具体的には時間部分を数値として扱うだけでよいのです。認識可能なものに戻ってその小数を変換するために持っているよりもあなたを

select avg(min(currentdate) - trunc(currentdate)), 
    avg(max(currentdate) - trunc(currentdate)) 
from transctn 
group by trunc(currentdate); 

しかし:たとえば、あなたが実際の時間とOracleが数値として返します一日の始まり、との差としての時間の部分を扱うことができ。

select to_char(date '2000-01-01' + avg(min(currentdate) - trunc(currentdate)), 
     'HH:MI pm') as avg_time_in, 
    to_char(date '2000-01-01' + avg(max(currentdate) - trunc(currentdate)), 
     'HH:MI pm') as avg_time_out 
from transctn 
group by trunc(currentdate); 

はこの厄介見て、あなたがより良い方法を見つけるかもしれない:それを行う1つの方法は、任意の固定日に番号を追加し、ちょうどあなたがすでにやっていたとして文字列として時刻部分を抽出することですそれをやる。それが宿題であれば、私はあなたにこのようなことをするための方法や適用可能なものを教えられたと思います。

これはすべてのリソースに適用されるため、1つのユーザーIDに制限するフィルタを追加する必要があります。うまくいけば、これは第2の要件にも取り組むためのいくつかのアイデアを提供します。

関連する問題