4

どこから始めればよいかを知っていても、助けを求めています。基本的に、雇用の開始日と終了日を保持するクライアント用のテーブルがあります。年次報告書の場合、ある終了日と次の開始日の間に21日を超えない限り、最も早い開始日から最後の終了日までとして定義される「継続雇用」を計算する必要があります。ここに例があります

employee | Start Date | End Date
1        | 2012-10-1  | 2012-11-05
1        | 2012-11-08 | 2013-1-25
2        | 2012-10-1  | 2012-11-05
2        | 2012-11-30 | 2013-1-02

上記では、従業員 1 が 2012 年 10 月 1 日から 2013 年 1 月 25 日まで継続的に雇用されていることを確認したいのですが、従業員 2 には 2012 年 10 月 1 日から 2012 年 11 月 5 日までの継続的な雇用を示す 2 つの個別の雇用ラインがあります。 012-11-30 から 2013-1-02 までとは異なります

助けてくれてありがとう!

4

2 に答える 2

3

理論は@mellamokbの答えに似ていますが、やや簡潔です:

SELECT employee, MIN(start) start, end
FROM (
  SELECT   @end:=IF(employee<=>@emp AND @stt<=end+INTERVAL 21 DAY,@end,end) end,
           @stt:=start start,
           @emp:=employee AS employee
  FROM     my_table, (SELECT @emp:=NULL, @stt:=0, @end:=0) init
  ORDER BY employee, start DESC
) t
GROUP BY employee, end

sqlfiddleで参照してください。

于 2013-04-25T16:29:42.730 に答える
2

一連のレコードの中から「連続グループ」を見つける方法の 1 つは、変数を使用して各行の違いを追跡し、連続範囲を組み合わせたグループを作成することです。以下の例では、3 つの変数を使用して、グループを生成するのに十分な情報を追跡しています。

  • @curEmployee - 前のレコードから現在の従業員を追跡し、現在のレコードの従業員と比較して、別の従業員にいつ切り替えたかを判断します。別の従業員は自動的に別のグループになります
  • @curEndDate - 前のレコードの最後の終了日を追跡するため、現在のレコードの開始日と比較して、現在のレコードが前のレコードと同じ「グループ」に属しているかどうかを確認できます。つまり、前歴のある継続雇用の一環
  • @curGroup - これは、継続的な雇用を表す個別の「グループ」に行を分離するキー変数です。ロジックは、次の 2 つの条件が真である場合にのみ、行が前の行と連続していると見なされる必要があるということです: 2 つの行の従業員番号が同じで、前の行の終了日が日付から 21 日未満である現在の行。
  • : 境界条件、つまり、正確に 20/21/22 日の間隔が継続雇用と見なされるかどうかを検証し、以下のロジックを微調整することをお勧めします。

これらのグループを計算するサンプル クエリを次に示します。select注意すべき点がいくつかあります。変数はリストの上から下に割り当てられるため、変数の割り当ての順序は重要です。前のレコードの値とのレコードから@curGroupの値を引き続き使用できるように、最初に割り当てる必要があります。次に、前のレコードと現在のレコードを比較するときに、それらが互いに最も近い 2 つのレコードであることを確認するために、句は非常に重要です。レコードをランダムな順序で見ると、最終的にすべて別々のグループになる可能性があります。@curEmployee@curEndDateorder by

select
  e.employee, e.`start date`, e.`end date`
  ,@curGroup :=
    case when employee = @curEmployee
      and @curEndDate + INTERVAL 21 DAY >= e.`start date`
        then @curGroup
        else @curGroup + 1
    end as curGroup
  ,@curEmployee := employee as curEmployee
  ,@curEndDate := e.`end date` as curEndDate
from
  employment e
JOIN (SELECT @curEmployee := 0, @curEndDate := NULL, @curGroup := 0) r
order by e.employee, e.`start date`

サンプル結果 ( DEMO ) -最初の 2 行CURGROUPが にとどまって1いることに注意してください。これらは互いに 21 日以内にあり、継続的な雇用を表しているためです。最後の 2 行は別のグループ番号として識別されます。

| EMPLOYEE |                      START DATE |                        END DATE | CURGROUP | CUREMPLOYEE |          CURENDDATE |
-------------------------------------------------------------------------------------------------------------------------------
|        1 |  October, 01 2012 00:00:00+0000 | November, 05 2012 00:00:00+0000 |        1 |           1 | 2012-11-05 00:00:00 |
|        1 | November, 08 2012 00:00:00+0000 |  January, 25 2013 00:00:00+0000 |        1 |           1 | 2013-01-25 00:00:00 |
|        2 |  October, 01 2012 00:00:00+0000 | November, 05 2012 00:00:00+0000 |        2 |           2 | 2012-11-05 00:00:00 |
|        2 | November, 30 2012 00:00:00+0000 |  January, 02 2013 00:00:00+0000 |        3 |           2 | 2013-01-02 00:00:00 |

継続雇用の一部であるレコードのグループを確立したので、これらのグループ番号でグループ化し、出力の最小および最大の日付範囲を見つけるだけです。

select
  employee,
  min(`start date`) as `start date`,
  max(`end date`) as `end date`
from (
    select
      e.employee, e.`start date`, e.`end date`
      ,@curGroup :=
        case when employee = @curEmployee
          and @curEndDate + INTERVAL 21 DAY >= e.`start date`
            then @curGroup
            else @curGroup + 1
        end as curGroup
      ,@curEmployee := employee as curEmployee
      ,@curEndDate := e.`end date` as curEndDate
    from
      employment e
    JOIN (SELECT @curEmployee := 0, @curEndDate := NULL, @curGroup := 0) r
    order by e.employee, e.`start date`
) as T
group by curGroup

サンプル結果 (デモ):

| EMPLOYEE |                      START DATE |                        END DATE |
--------------------------------------------------------------------------------
|        1 |  October, 01 2012 00:00:00+0000 |  January, 25 2013 00:00:00+0000 |
|        2 |  October, 01 2012 00:00:00+0000 | November, 05 2012 00:00:00+0000 |
|        2 | November, 30 2012 00:00:00+0000 |  January, 02 2013 00:00:00+0000 |
于 2013-04-25T16:20:29.007 に答える