1

単純な雇用履歴データベースがあり、エントリ ID、ユーザー ID、仕事、開始日と終了日を保存しています。エントリーが重複する場合があります。特定の期間に、特定の時間枠の休憩がないことを確認する必要があります。

したがって、user_id 1には次のような作業履歴があります

Marketing - 01/01/2013 to 19/05/2013
Sales - 01/01/2011 to 01/05/2012
Admin - 01/01/2010 to 31/12/2010

私は実際に日付をUNIXタイムスタンプとして保存しています。3 年間の履歴で、user_id 1 は営業職とマーケティング職の間に 6 か月以上の休憩があります。彼らがこの期間のエントリを提供できるように、どうすればこれにフラグを立てることができますか?

4

2 に答える 2

2

職歴が重複する可能性があるため、この問題は思ったより難しいです。実際、ある雇用期間を別の雇用期間の「中に」入れることも、両端で重複させることもできます。

探しているのは、開始日までのギャップがあり、別の雇用期間にない EndDateです。そこで、次のように、相関サブクエリを使用して、終了日の後の次の開始日を取得しましょう。

     select t.*,
             (select StartDate
              from t t2
              where t2.user_id = t.user_id and
                    t2.StartDate > t.EndDate
              order by StartDate desc
              limit 1
             ) nextStartDate
      from t

さて、問題は次のとおりです。期間は別の期間に含まれています。このために、複雑なwhere句を使用します。

select t.*
from (select t.*,
             (select StartDate
              from t t2
              where t2.user_id = t.user_id and
                    t2.StartDate > t.EndDate
              order by StartDate desc
              limit 1
             ) nextStartDate
      from t
     ) t
where not exists (select 1
                  from t t2
                  where t2.StartDate <= t.EndDate and
                        t2.EndDate >= t.nextStartDate
                 ) and
      (t.EndDate is null or t.EndDate > now())

オーバーラップをどのように処理しているかによっては、日付の間に数日のラグを許容したい場合があります。

これにより、ギャップがあるテーブル内のすべてのレコードが返されます。サンプル データでは、今日 (2013-05-19) のレコードが返されます。「販売」の記録は、その後「マーケティング」の位置までギャップがあります。「マーケティング」は、過去に終了しているため、将来返されます。

実際には、1 つのギャップによって複数のレコードが返される可能性があります。これは、オーバーラップがある場合に発生する可能性があります。これについては、(0, 10)、(5, 12)、(15, 20) の数字だけで説明します。12/13 から始まるギャップは両方の記録に影響します。これが問題であれば、クエリを修正することができますが、それを修正する方法について最初に考えた場合、クエリはさらに複雑になります。

whereおそらく、最も外側の句に入れることができるユーザーIDでもフィルタリングします。

于 2013-05-19T15:40:35.297 に答える
0

次のようなものを探します。

<?php
    $time_allowed = '1 month';

    $person = [
        [
            1305819929, // 19-05-11
            1337442341  // 19-05-12
        ],

        [
            1337442341, // 19-05-12
            1345933614  // 26-08-12
        ],

            // almost 4 month gap here - this will result in flagged() getting triggered

        [
            1355935614, // 19-12-12
            1368978787  // 19-05-13
        ]
    ];

    $time_allowed = strtotime('now') - strtotime("-{$time_allowed}");

    foreach($person as $key => $job)
    {
        if( ! isset($person[$key + 1]))
        {
            if($job[1] !== 'current' && (strtotime('now') - $job[1]) > $time_allowed)
            {
                flagged();
            }
        }
        else
        {
            if(($person[$key + 1][0] - $job[1]) > $time_allowed)
            {
                flagged();
            }
        }
    }

    function flagged()
    {
        // user flagged
    }

明らか$personに、データベースから取得されます。スクリプトは一目瞭然です。

于 2013-05-19T15:39:50.627 に答える