我有一个包含以下内容的数据集:
Table { date itemName }
这个日期大部分是顺序排列的。由于它是主键,因此没有重复的日期。
这个问题分成多个部分(都涉及使用SQL):
- 是否可以找到表中列出的日期系列中的间隙?
例如:日期
1/2/09-1/3/09
缺失。 - 是否可以找到在表中缺失的日期段,其范围大于n(n是运行时确定的数字)?例如:对于
n=2
,日期1/2/09-1/3/09
不会被返回,但日期5/6/09-6/1/09
会被返回。
我有一个包含以下内容的数据集:
Table { date itemName }
这个日期大部分是顺序排列的。由于它是主键,因此没有重复的日期。
这个问题分成多个部分(都涉及使用SQL):
1/2/09-1/3/09
缺失。n=2
,日期 1/2/09-1/3/09
不会被返回,但日期 5/6/09-6/1/09
会被返回。如果您可以使用PostgreSQL 8.4,那么窗口函数会有所帮助:
SELECT *
FROM (SELECT itemName, date, date - lag(date) OVER w AS gap
FROM someTable WINDOW w AS (ORDER BY date)
) AS pairs
WHERE pairs.gap > '1 day'::interval;
只需在PL/SQL或客户端中创建一个函数,该函数将检查所有日期。就像这样的伪代码:
date checked_date = 2000-01-01;
int unchecked_section = 0;
while ( checked_date <= today() ) {
if (! sql(select itemName from Table where itemName=checked_date)) {
unchecked_section++;
} else {
if ( unchecked_section>=n ) {
print checked_date-unchecked_section, checked_date
}
unchecked_section = 0;
}
checked_date++;
}
if ( unchecked_section ) {
print checked_date-unchecked_section, checked_date
}
由于这只是维护工作,所以速度不必太快。每年需要检查的日期也不多,仅有365天。
SELECT date, itemName
FROM "Table" as t1
WHERE NOT EXISTS (
SELECT date
FROM "Table" as t2
WHERE t2.date = (t1.date - INTERVAL '1 day')
)
ORDER BY date
OFFSET 1 -- this will skip the first element
这将获取所有没有直接后继的行。
如果您修改语句为:
SELECT date, itemName
FROM "Table" as t1
WHERE NOT EXISTS (
SELECT date
FROM "Table" as t2
WHERE (t2.date >= (t1.date - INTERVAL '2 day'))
AND (t2.date < t1.date)
)
ORDER BY date
OFFSET 1
你可以在子查询的WHERE子句中使用INTERVAL长度来过滤至少具有该大小间隔的数据。
希望这能帮到你。