7

不在の詳細という名前のテーブルがあり、連続した日付をグループ化したいと考えています。では、データです

EID        AbsenceType  AbsenceStartDate               AbsenceEndDate
769     Holiday     2012-06-25  00:00:00.000            2012-06-25 23:59:59.000
769     Holiday     2012-06-26  00:00:00.000            2012-06-26 23:59:59.000
769     Holiday     2012-09-03  00:00:00.000            2012-09-03 23:59:59.000
769     Holiday     2012-09-04  00:00:00.000            2012-09-04 23:59:59.000
769     Holiday     2012-09-05  00:00:00.000            2012-09-05 23:59:59.000
769     Holiday     2012-09-06  00:00:00.000            2012-09-06 23:59:59.000
769     Holiday     2012-09-07  00:00:00.000            2012-09-07 23:59:59.000

私が得ようとしている結果は

EID     AbsenceType AbsenceStartDate          AbsenceEndDate
769     Holiday     2012-06-25  00:00:00.000         2012-06-26 23:59:59.000
769     Holiday     2012-09-03  00:00:00.000         2012-09-07 23:59:59.000

どんな助けでも大歓迎です。

4

4 に答える 4

4

主な問題を切り分けるために、シナリオを簡略化しました。このテーブルにギャップがあるとしましょう。

with ns as (
select 1 as n union
select 2 as n union
select 3 as n union
select 8 as n union    --gap
select 9 as n )
select * 
into #ns
from ns;

今、あなたが期待している結果は次のとおりです。

ini fi 
--- -- 
1   3  
8   9  

この結果を取得するには、次の方法でデータをマッサージします。最初に開始期間と終了期間の2つのビューを作成し、次に両方のビューを結合して最終結果を取得します。テーブルを自分で結合して、開始期間と終了期間を見つけていることに注意してください。

with 
inis as                                     -- identifying start periods
(
   select n1.n
   from #ns n1
   left outer join #ns n2 
       on n1.n = n2.n + 1
   where n2.n is null
   ),
fis as                                      -- identifying ends periods
( 
   select n1.n 
   from #ns n1
   left outer join #ns n2 
       on n1.n = n2.n - 1
   where n2.n is null
   )  
select inis.n as ini, min( fis.n ) as fi    -- joining starts and ends
from inis 
inner join fis 
  on inis.n <= fis.n
group by inis.n
;
   

この手法をデータおよびデータ型に転送できます。クエリの翻訳で問題が発生した場合は、お気軽にお問い合わせください。

クエリと結果を確認します。

于 2012-09-19T09:01:53.043 に答える
4

これが私のために働いた解決策です。

SELECT EID, AbsenceType, MIN(AbsenceStartDate) AS AbsenceStartDate, MAX(AbsenceEndDate) AS AbsenceEndDate
FROM (SELECT EID, AbsenceType, AbsenceStartDate, AbsenceEndDate,
      DATEADD(dd, - ROW_NUMBER() OVER (PARTITION BY EID, AbsenceType ORDER BY EID,AbsenceStartDate), AbsenceStartDate)
      FROM AbsenceDetails
      GROUP BY EID,AbsenceType,AbsenceStartDate,AbsenceEndDate
      ) a(EID, AbsenceType, AbsenceStartDate, AbsenceEndDate, Grp)
GROUP BY EID, AbsenceType, Grp;
于 2012-09-19T10:45:23.367 に答える
1

私は次のようにします:

  1. 一連の欠勤日のリストを特定します。

    SELECT
        ad1.EID, ad1.StartDate, ad2.EndDate
    FROM 
        AbsenceDetails ad1
        JOIN AbsenceDetails ad2
        ON ad1.EID = ad2.EID
    WHERE
        DATEDIFF(ss, ad1.EndDate, ad2.StartDate) = 1
    

    結果は次のようになります。

    769 2012-06-25 00:00:00.000 2012-06-26 23:59:59.000
    769 2012-09-03 00:00:00.000 2012-09-04 23:59:59.000
    769 2012-09-04 00:00:00.000 2012-09-05 23:59:59.000
    769 2012-09-05 00:00:00.000 2012-09-06 23:59:59.000
    769 2012-09-06 00:00:00.000 2012-09-07 23:59:59.000
    
  2. リストを反復処理し、各ストレッチの開始時間と終了時間を特定します。これは、アプリ層で行う方が適切です。

于 2012-09-19T08:53:45.083 に答える
0

私があなたの質問を正しく理解したなら、あなたはあなたの記録で連続した時間間隔を見つけたいと思っています.
主な問題は、連続した時間間隔を実際に構成するものを特定すること
です 。

date1.09:00 to date1.18:00  
date2.09:00 to date2.18:00  

連続と見なすことができる 翌date2営業日です。date1

あなたの場合は比較的簡単ですが、単一のクエリでは実行できません。少なくとも今はそれを行う方法が思い浮かびません。

「podiluska」によって提案されたPS「Islands and Gaps」アルゴリズムは、単一のクエリ/ストアドプロシージャで記述するのに役立ちます。

于 2012-09-19T08:52:47.547 に答える