SQL 小提琴演示
我不知道 sqllite 是否具有排名功能,这会使解决方案变得更容易,但以下语句应该适用于任何符合 ANSI-92 的 DBMS。
解决方案的要点是
- Step1:获取所有
error
ID
- Step2:通过使用 GROUP BY 子句获取所有 ID < 根 ID,并加入相同的查询以检索原始错误 ID
- Step3:与第二步类似,但下降一个层次。
SQL 语句
SELECT ID
FROM (
-- Select the ROOT value
SELECT ID, 0 AS GroupID
FROM thetable
WHERE value = 'error'
UNION ALL
-- Selects the ROOT value - 1
SELECT MAX(t.ID) AS ID, te.ID AS GroupID
FROM thetable AS t
INNER JOIN (
SELECT ID
FROM thetable
WHERE value = 'error'
) AS te ON te.ID > t.ID
GROUP BY
te.ID
UNION ALL
-- Selects the ROOT value - 1 - 1
SELECT MAX(t.ID), te.ID
FROM thetable AS t
INNER JOIN (
SELECT MAX(t.ID) AS ID, te.ID AS GroupID
FROM thetable AS t
INNER JOIN (
SELECT ID
FROM thetable
WHERE value = 'error'
) AS te ON te.ID > t.ID
GROUP BY
te.ID
) AS te ON te.ID > t.ID
GROUP BY
te.ID
) AS t
ORDER BY
ID
编辑
FWIW:如果 SQLite 允许排名函数和 cte 的,下面的语句返回相同的结果,但更简洁。
;WITH q AS (
SELECT ROW_NUMBER() OVER (ORDER BY ID) rn
, ID
, value
FROM thetable
)
SELECT q2.ID
FROM q q1
INNER JOIN q q2 ON q2.rn BETWEEN q1.rn - 2 AND q1.rn
WHERE q1.value = 'error'