SQL筛选器仅用于连续数字
我有一个按时间戳排序的表,我只想保留下面用*标记的连续顺序的步骤。 在命令式编程中,它将是: 上一步=0 输出=[] 对于表中的步骤。步骤:已按时间戳排序 如果步骤==上一步+1: output.appendstep所需行 上一步=下一步 我想要的原始表中的行用*装饰,而不是实际数据:SQL筛选器仅用于连续数字,sql,oracle12c,Sql,Oracle12c,我有一个按时间戳排序的表,我只想保留下面用*标记的连续顺序的步骤。 在命令式编程中,它将是: 上一步=0 输出=[] 对于表中的步骤。步骤:已按时间戳排序 如果步骤==上一步+1: output.appendstep所需行 上一步=下一步 我想要的原始表中的行用*装饰,而不是实际数据: | timestamp | step | | --------- | ---- | | 100000001 | 5 | | 100000002 | 1 |* | 100000003 | 1 |
| timestamp | step |
| --------- | ---- |
| 100000001 | 5 |
| 100000002 | 1 |*
| 100000003 | 1 | ^
| 100000004 | 2 |*
| 100000005 | 2 | ^
| 100000006 | 4 |
| 100000007 | 5 |
| 100000008 | 3 |*
| 100000009 | 4 |*
| 100000010 | 2 |
| 100000011 | 5 |*
| 100000012 | 7 |
我想要的是:
| timestamp | step |
| --------- | ---- |
| 100000002 | 1 |*
| 100000004 | 2 |*
| 100000008 | 3 |*
| 100000009 | 4 |*
| 100000011 | 5 |*
我只找到了一个WHERE-step-lag-OVER-orderby-timestamp 0,但这只删除了上面^中标记的相邻重复项。这当然有帮助,但还没有完全实现
提前谢谢 这里有一个解决方案,它依赖于相关子查询来检测每个步骤要保留的正确记录
WITH cte AS (
SELECT t1.*, (SELECT COUNT(DISTINCT t2.step) FROM yourTable t2
WHERE t2."timestamp" < t1."timestamp" AND t2.step < t1.step) AS cnt
FROM yourTable t1
),
cte2 AS (
SELECT t.*, ROW_NUMBER() OVER (PARTITION BY cnt ORDER BY step, "timestamp") rn
FROM cte t
)
SELECT t1."timestamp", t1.step, t1.rn, t1.cnt
FROM cte2 t1
WHERE rn = 1 AND (step = 1 OR EXISTS (SELECT 1 FROM yourTable t2
WHERE t2.step = t1.step - 1))
ORDER BY "timestamp";
一种方法是递归CTE。不幸的是,递归CTE有一些限制。因此,一种方法是按步骤顺序生成通过数据的每条路径。然后为每个步骤选择最小的时间戳:
with cte(ts, step) as (
(select ts, step
from t
where step = 1
order by ts
fetch first 1 row only)
union all
select t.ts, t.step
from cte join
t
on t.ts >= cte.ts and t.step = cte.step + 1
)
select *
from (select cte.*,
row_number() over (partition by step order by ts) as seqnum
from cte
) cte
where seqnum = 1;
是一把小提琴。谢谢你的回答!它是有效的,但是WHERE子句应该是WHERE rn=1和step=cnt+1吗?我还发现了一个场景,其中这两个where子句都无法处理@LeightonRitchie,我只能根据您提供的数据进行回答。是的,我可能遗漏了一些边缘案例。如果戈登的回答对你有帮助的话,也许可以试试。