2014-01-21 3 views
0

나는 Ingres 테이블에 다음과 같은 데이터가 있습니다.체크 날짜 분할 기간은 연속입니다.

REF  FROM_DATE TO_DATE 
A  01.04.1997 01.04.1998 
A  01.04.1998 27.05.1998 
A  27.05.1998 01.04.1999 

B  01.04.1997 01.04.1998 
B  01.04.1998 26.07.1998 
B  01.04.2012 01.04.2013 

일부 심판은 최대 (TO_DATE)의 분 (FROM_DATE)에 연속 기간을 가지고 있지만, 어떤 기간에 차이가있다.

나는 Ingres SQL에서 어떤 refs가 날짜 기간에 간격이 있는지 식별하는 방법을 알고 싶습니다.

Ingres sql 명령을 호출하는 Unix 셸 스크립트로이 작업을 수행하고 있습니다.

알려 주시기 바랍니다.

답변

1

Ingres의 날짜 기능에 익숙하지 않습니다. -이 며칠 만에 두 날짜의 차이를 얻는다 고 가정합시다.

데이터에 겹침이 없으면 원하는 것을 쉽게 할 수 있습니다. 간격이없는 경우, 최소 날짜와 최대 날짜의 차이는 각 행의 차이점의 합과 같습니다. 차이가 0보다 큰 경우에는 간격이 있습니다.

그래서 :

select ref, 
     ((max(to_date) - min(from_date)) - 
     sum(to_date - from_date) 
     ) as total_gaps 
from t 
group by ref; 

나는이 사건에서 작동합니다 생각합니다. 다른 경우에는 종료일이 기간에 포함되는지 여부에 따라 "off-by-1"문제가있을 수 있습니다.

+0

이러한 접근 방식을 사용하면 어느 ref에 간격이 있는지 식별 할 수 있지만 간격을 나열 할 수는 없습니다. – Qsebas

+0

@ Qsebas. . . "Ingres SQL에서 어떤 REF가 날짜 간격에 차이가 있는지 확인하는 방법을 알고 싶습니다." –

+0

예! 확실한! 당신의 접근 방식은 질문에 대답하기에 더 짧고 충분합니다. 하지만 _MAYBE_ 누군가가 필요에 따라 틈새를 나열하는 데 신경을 써야하며 (그렇다면 광산과 같은) 더 복잡한 쿼리가 필요할 경우 ... 대답을 +1 할 것입니다. 더 짧고 명확하게 :) – Qsebas

0

이 쿼리는 SQL SERVER에서 작동합니다. PARTITION은 ANSI SQL 명령이므로 INGRES가 지원하는지 여부는 알 수 없습니다. 파티션이 아마 지원되는 경우 주어진 예제의 결과 Dense_Rank()

select * 
INTO #TEMP 
from (
select 'A' as Ref, Cast('1997-01-04' as DateTime) as From_date, Cast('1998-01-04' as DateTime) as to_date 
union 
select 'A' as Ref, Cast('1998-01-04' as DateTime) as From_date, Cast('1998-05-27' as DateTime) as to_date 
union 
select 'A' as Ref, Cast('1998-05-27' as DateTime) as From_date, Cast('1999-01-04' as DateTime) as to_date 
union 
select 'B' as Ref, Cast('1997-01-04' as DateTime) as From_date, Cast('1998-01-04' as DateTime) as to_date 
union 
select 'B' as Ref, Cast('1998-01-04' as DateTime) as From_date, Cast('1998-07-26' as DateTime) as to_date 
union 
select 'B' as Ref, Cast('2012-01-04' as DateTime) as From_date, Cast('2013-01-04' as DateTime) as to_date 
) X 

    SELECT * 
    FROM 
    (
      SELECT Ref, Min(NewStartDate) From_Date, MAX(To_Date) To_Date, COUNT(1) OVER (PARTITION BY Ref) As [CountRanges] 
      FROM 
      (

       SELECT Ref, From_Date, To_Date, 
         NewStartDate = Range_UNTIL_NULL.From_Date + NUMBERS.number, 
         NewStartDateGroup =  DATEADD(d, 
                1 - DENSE_RANK() OVER (PARTITION BY Ref ORDER BY Range_UNTIL_NULL.From_Date + NUMBERS.number), 
                Range_UNTIL_NULL.From_Date + NUMBERS.number) 
       FROM 
       (

        --This subquery is necesary needed to "expand the To_date" to the next day and allowing it to be null 
         SELECT 
          REF, From_date, DATEADD(d, 1, ISNULL(To_Date, From_Date)) AS to_date 
         FROM #Temp T1 
         WHERE 
          NOT EXISTS ( SELECT * 
              FROM #Temp t2 
              WHERE T1.Ref = T2.Ref and T1.From_Date > T2.From_Date AND T2.To_Date IS NULL 
             ) 
       ) AS Range_UNTIL_NULL 
       CROSS APPLY Enumerate (ABS(DATEDIFF(d, From_Date, To_Date))) AS NUMBERS 
        ) X 
      GROUP BY Ref, NewStartDateGroup 
    ) OVERLAPED_RANGES_WITH_COUNT 
-- WHERE OVERLAPED_RANGES_WITH_COUNT.CountRanges >= 2 --This filter is for identifying ranges that have at least one gap 
    ORDER BY Ref, From_Date 

에 상응하는 것이다 것은 :

Ref From_Date    To_Date     CountRanges 
---- ----------------------- ----------------------- ----------- 
A 1997-01-04 00:00:00.000 1999-01-05 00:00:00.000 1 
B 1997-01-04 00:00:00.000 1998-07-27 00:00:00.000 2 
B 2012-01-04 00:00:00.000 2013-01-05 00:00:00.000 2 

는 "CountRanges"> (1)가 적어도 하나가를 갖는 심판을 볼 수 격차

이 대답은 지금까지 초기 질문 beyound가는 이유는

  1. R 단지 간격이있는 심판 요청하지만,이 쿼리는 격차를
  2. 아시고 쿼리를 나열 할 수 있습니다
  3. 문제를 발생할 수있는 초기 문제의 경우 Anges의 overlaped 할 수는 명확하지 않다 반 세그먼트를 나타내는, 널 (null)에 TO_DATE 수 있습니다 무한대로