检查日期分割期是连续的

时间:2014-01-21 12:14:59

标签: sql ingres

我在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

有些裁判从min(from_date)到max(to_date)有连续的句号,但有些裁词在这段时间内有差距。

我想知道Ingres SQL中识别哪些引用在日期中有差距的方法。

我这样做是作为调用Ingres sql命令的Unix shell脚本。

请告知。

2 个答案:

答案 0 :(得分: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”问题,具体取决于结束日期是否包含在期间内。

答案 1 :(得分: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至少有一个差距

这个答案远远超出了最初的问题,因为:

  1. 范围可以重叠,如果在初始问题中可能发生则不清楚
  2. 问题只是询问哪些参考文章有差距,但使用此查询可以列出差距
  3. Tis查询允许To_date为null,表示半段为无限