私は最近、雇用の日付間のギャップを見つけることを任されました。ギャップは、ある仕事の終了から次の開始までの期間が 30 日を超えると定義され、次のクエリを思い付くことができました。それに合わせて、以下を参照してください。
WITH GapsInEmployment AS
(
SELECT
-1 AS DriverQualificationApplicationEmploymentGapId
,E1.DriverQualificationApplicationId
,E1.EndDate AS EmploymentGapBeginDate
,E2.StartDate AS EmploymentGapEndDate
,(
CASE
WHEN ISNULL(DATEDIFF(DD, E1.EndDate, E2.StartDate), 0) < 0 THEN 0
ELSE DATEDIFF(DD, E1.EndDate, E2.StartDate)
END
) AS DaysLapsedBetweenEmployment
,NULL AS ReasonForEmploymentGap
FROM @EmploymentGapInfo E1
LEFT JOIN @EmploymentGapInfo E2
ON E1.RowNum = E2.RowNum - 1
)
SELECT *
FROM GapsInEmployment
WHERE DaysLapsedBetweenEmployment > 30;
1 つのレコードを次のレコードと比較して、最初のレコードの終了日と 2 番目のレコードの開始日の間に 30 日の経過があるかどうかを確認しています。これは「通常の」ケースでは問題なく機能します。つまり、雇用期間が重複していません。誰かが特定の期間に複数の仕事を持っており、ジョブ A の期間が従業員がジョブ B を持っていた期間の間にあるという特定のケースが発生しました。上記のクエリで実行するテスト データは次のとおりです。
DECLARE @EmploymentGapInfo TABLE
(
RowNum INT IDENTITY(1, 1)
,DriverQualificationApplicationEmploymentId INT
,DriverQualificationApplicationId INT
,StartDate DATETIME
,EndDate DATETIME
);
INSERT INTO @EmploymentGapInfo
SELECT -1, 766, '10/14/2003', '11/07/2003';
INSERT INTO @EmploymentGapInfo
SELECT -1, 766, '08/28/2006', '06/15/2011';
INSERT INTO @EmploymentGapInfo
SELECT -1, 766, '08/22/2011', '10/23/2012';
INSERT INTO @EmploymentGapInfo
SELECT -1, 766, '06/01/2012', '07/01/2012';
INSERT INTO @EmploymentGapInfo
SELECT -1, 766, '11/01/2012', '03/05/2013';
INSERT INTO @EmploymentGapInfo
SELECT -1, 766, '10/14/2013', NULL;
クエリを実行すると、2012 年 7 月 1 日から 2012 年 11 月 1 日までの雇用ギャップが誤って計算されます。これは、そのレコードの開始日と終了日が前のレコードの間で始まるため、正しくありません。クエリは、ギャップに対して次の結果セットを生成する必要があります。
2003 年 11 月 7 日 -> 2006 年 8 月 28 日
2011 年 6 月 15 日 -> 2011 年 8 月 22 日
2013 年 3 月 5 日 -> 2013 年 10 月 14 日
私の問題は、カーソルなしでこれを正しく計算する方法を考え出そうとしているということです.EmploymentGapInfoテーブル変数の各レコードをループする必要があるためです.そのレコードの終了日を確認するには、テーブルを再度ループして、開始日と終了日がテーブル内の他のレコードと重複しているかどうかを確認します。
カーソルを使用する代わりに、セットベースのアプローチでこの問題に取り組む方法はありますか? これは、データベースで解決しようとするのではなく、ビジネス レイヤーで実行することでメリットが得られる問題でしょうか?
どんな助けでも大歓迎です。