2012-02-10 32 views
1

我们有一张表,其中包含订阅产品的状态更新。订阅开始时,表中会插入一条记录,并且订阅结束时该记录会更新为结束日期。我们的系统之一(不知道哪一个系统)有时会在“同一天下落\添加”结束订阅,然后再次开始(创建新记录)。因此,即使没有真正改变,相同的订户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,我相信。

+0

存在使用会产生预期的结果窗口集合函数以及所述一个正确下文标识的溶液。如果我有时间,我也会尽力写出来。 – 2012-02-13 15:01:41

回答

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...

+0

这太神奇了。非常感谢!!!为了能够在合理的时间内运行(表格非常庞大),我必须使用计时器,所以我创建了一个包含在我的学习开始日期后开始或结束的任何记录的送纸器表,然后使用您的代码,然后在我的学习开始日期之前删除任何显示的内容。像冠军一样工作! – user548084 2012-02-10 22:02:45

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语句,并使用存储过程,或将所有数据返回给客户端并在那里处理。

相关问题