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

一些 refs 有从 min(from_date) 到 max(to_date) 的连续周期,但有些在周期中有间隙。

我想知道在 Ingres SQL 中识别哪些参考在日期期间有间隙的方法。

我将其作为调用 Ingres sql 命令的 Unix shell 脚本来执行。

请指教。

4

2 回答 2

1

我不熟悉 Ingres 中的日期函数。让我假设这-会在几天内获得两个日期之间的差异。

如果数据中没有重叠,那么你可以很容易地做你想做的事。如果没有间隙,则最小日期和最大日期之间的差异与每行差异的总和相同。如果差值大于 0,则存在间隙。

所以:

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

我相信这将适用于您的情况。在其他情况下,可能会出现“偏离 1”的问题,具体取决于结束日期是否包含在期间中。

于 2014-01-21T13:41:18.573 回答
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,表示半段到无限
于 2014-01-21T14:16:08.360 回答