我有一个包含以下内容的数据集:
Table { date itemName }
大部分日期是顺序的。日期没有重复[因为它是主键]。
问题分为多个部分(全部都与使用SQL有关):
1/2/09-1/3/09
n = 2
日期1/2/09-1/3/09
未返回,但日期5/6/09-6/1/09
为。答案 0 :(得分:10)
如果您可以使用PostgreSQL 8.4,那么window functions将有所帮助:
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;
答案 1 :(得分:1)
只需在plsql或客户端创建一个函数,它将检查所有日期。像这个伪代码:
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个。
答案 2 :(得分:1)
经过一些测试后,我想出了以下SQL语句:
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
你可以使用subselect的WHERE子句中的INTERVAL长度来过滤至少那个大小的间隙。
希望有所帮助。