2012-01-27 12 views
0

私は従業員のタイムシートを管理するアプリケーションを持っています。Oracle:日付フィールドに基づいてレコードにギャップがあるかどうかを確認するにはどうすればよいですか?

私のテーブルは次のようになります。

TIMESHEET 
    TIMESHEET_ID 
    EMPLOYEE_ID 
    etc 

TIMESHEET_DAY: 
    TIMESHEETDAY_ID 
    TIMESHEET_ID 
    DATE_WORKED 
    HOURS_WORKED 

たびシートは、14日間の期間をカバーするので、各タイムシートレコードの14件のTIMESHEET_DAYレコードがあります。誰かが休暇を取った場合、その14日間に何時間も働いていなければ、タイムシートを入力する必要はありません。

ここで、従業員が過去6ヶ月間に7日間のギャップを取っているかどうかを判断する必要があります。これは、0時間で7つの連続したTIMESHEET_DAYレコードを検索しなければならないことを意味します。または、レコードが提出されず、0時間で提出されたレコードの組み合わせで7日間の期間が検索されなければなりません。その場合は、最後のTIMESHEET_DAYレコードのDATE_WORKEDと時間を知る必要があります。

アプリケーションはasp.netですので、すべてのTIMESHEET_DAYレコードを取得して繰り返し処理できますが、SQLでこれを行うにはより効率的な方法が必要です。

+0

を正直なところ、私もどこを開始するのか分かりません。 – chris

+0

私はLAG関数でこれにアプローチします。もし私が時間を取れば、私は試してみるかもしれません。 – Randy

+0

@Randy:私はこのアプローチを検討していますが、BIの機能に関する多くの経験はないので、どんな提案も感謝します。 – chris

答えて

0

少なくとも部分的には、タイムシートごとの日数を数え、プログラムのロジックの残りの部分を実行することでSQLを実行します。これは行方不明の日にタイムシートを識別します

SELECT * FROM 
    (SELECT s.timesheet_id, SUM(CASE WHEN d.hours_worked > 0 THEN 1 ELSE 0 END) AS days_worked 
    FROM 
     TimeSheet s 
     LEFT JOIN TimeSheet_Day d 
      ON s.timesheet_id = d.timesheet_id 
    GROUP BY 
     s.timesheet_id 
    HAVING SUM(CASE WHEN d.hours_worked > 0 THEN 1 ELSE 0 END) < 14) X 
    INNER JOIN TimeSheet 
     ON TimeSheet.timesheet_id = X.timesheet_id 
    LEFT JOIN TimeSheet_Day 
     ON TimeSheet.timesheet_id = TimeSheet_Day.timesheet_id 
    ORDER BY 
     TimeSheet.employee_id, TimeSheet.timesheet_id, TimeSheet_Day.date_worked 
+0

これは、2つのタイムシートにまたがって起こる可能性のあるギャップを特定するのに役立つものではありません。 – chris

+0

自分のSQLを更新しました。すべてのレコードを返すのではなく、少なくとも問題の可能性のあるレコードを返すことができます。しかし、連続する失われた日を検出するためには、まだいくつかのプログラムロジックが必要です。 –

1
SELECT t1.EMPLOYEE_ID, t1.TIMESHEETDAY_ID, t1.DATE_WORKED 
FROM (SELECT ROW_NUMBER() OVER(PARTITION BY EMPLOYEE_ID, TIMESHEETDAY_ID ORDER BY DATE_WORKED) AS RowNumber, 
      EMPLOYEE_ID, TIMESHEETDAY_ID, DATE_WORKED 
     FROM (SELECT EMPLOYEE_ID, TIMESHEETDAY_ID, DATE_WORKED  
      FROM TIMESHEET_DAY d 
        INNER JOIN TIMESHEET t ON t.TIMESHEET_ID = d.TIMESHEET_ID 
      GROUP BY EMPLOYEE_ID, TIMESHEETDAY_ID, DATE_WORKED 
      HAVING SUM(HOURS_WORKED) > 0) t) t1 
    INNER JOIN  
    (SELECT ROW_NUMBER() OVER(PARTITION BY EMPLOYEE_ID, TIMESHEETDAY_ID ORDER BY DATE_WORKED) AS RowNumber, 
      EMPLOYEE_ID, TIMESHEETDAY_ID, DATE_WORKED 
     FROM (SELECT EMPLOYEE_ID, TIMESHEETDAY_ID, DATE_WORKED  
      FROM TIMESHEET_DAY d 
        INNER JOIN TIMESHEET t ON t.TIMESHEET_ID = d.TIMESHEET_ID 
      GROUP BY EMPLOYEE_ID, TIMESHEETDAY_ID, DATE_WORKED 
      HAVING SUM(HOURS_WORKED) > 0) t) t2 ON t1.RowNumber = t2.RowNumber + 1 
WHERE t2.DATE_WORKED - t1.DATE_WORKED >= 7 
+0

'DATEDIFF'はOracleの機能ではありません –

+0

@a_horse_with_no_nameが固定されました。ありがとう! –

関連する問題