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