排除当天下降\添加,同时保留真正的开始和结束日期

时间:2012-02-10 20:23:16

标签: sql teradata gaps-and-islands ansi-sql

我们有一个表格,其中包含订阅产品的状态更新。订阅开始时将记录插入表中,并在订阅结束时使用结束日期更新该记录。我们的一个系统(不知道哪一个)有时会在结束订阅然后再次开始(创建新记录)时“同一天下降\添加”。因此,即使没有真正改变,也会将相同的订户ID附加到多个记录。

示例数据将是:

recID subID   start           end        prodtype
1     19    01/11/2001  01/15/2001    A
2     19    01/15/2001  01/16/2001    A
3     19    01/16/2001  01/20/2001    A
4     19    01/30/2001  01/31/2001    A

这家伙于1/11开始,于1/20结束。记录2和3由系统输入(同一天下降添加,但不是真的)。记录4是19岁先生开始的另一项订阅。

我有一些代码会尝试仅解析每个不同订阅的第一条(真实的)记录,但是如果没有使用max()和订阅者分组,它就无法找到真实的结束日期。那当然会显示两个订阅,1/11 - 1/31和1/30 - 1/31,这是错误的。

我正在试图将这种模式解决为两个这样的记录:

subID   start           end        prodtype
 19    01/11/2001   01/20/2001    A
 19    01/30/2001   01/31/2001    A

这是在Teradata,但我相信它只是ANSI SQL。

2 个答案:

答案 0 :(得分:0)

您可以使用以下代码找到所有包含实际结束日期的记录:

select t1.*
from myTable t1 left outer join myTable t2 on
t1.SubID = t2.SubID and  
t1.end = t2.start and t2.start is null

当然,你可以用类似的方式找到开始记录。那么也许你可以将它们拼凑在一起。

也就是说,有时候放弃对select语句进行所有处理,并使用存储过程,或者将所有数据带回客户端并在那里进行处理。

答案 1 :(得分:0)

我相信这是ANSI SQL,但我只在SQL Server上测试过它。

基本上,查询能够相互独立地找到真正的开始日期和真实的结束日期。然后关联开始日期和结束日期,将开始日期与结束日期相关联,大于开始日期...然后显示最小结束日期。

SELECT
    startDates.subId,
    startDates.startDate,
    MIN(endDates.endDate) AS endDate,
    startDates.prodType
FROM
(
    SELECT
        recID, subID, startDate, prodType
    FROM yourTable s1
    WHERE NOT EXISTS (
        SELECT 1
        FROM yourTable s2
        WHERE 
            s1.startDate = s2.endDate
            AND s1.subId = s2.subId
    )
) startDates JOIN
(
    SELECT
        recID, subID, endDate, prodType
    FROM yourTable s1
    WHERE NOT EXISTS (
        SELECT 1
        FROM yourTable s2
        WHERE 
            s1.endDate = s2.startDate
            AND s1.subId = s2.subId
    )
) endDates ON
    startDates.subID = endDates.subID 
    AND startDates.startDate < endDates.endDate
GROUP BY
    startDates.subId,
    startDates.startDate,
    startDates.prodType

Here is the query in action...