1

我想在具有指定值的行之前获得 2 个行 ID。

所以我在表中有 ID 和值

ID   value
1,   x
3,   x 
7,   x
8,   error
9,   x
10.  x
11,  x
12   error

我想要错误之前的两行。

我可以使用硬编码的错误行 ID 来做到这一点

SELECT id FROM thetable WHERE id < 8 ORDER BY ID DESC LIMIT 2  
UNION ALL
SELECT id FROM thetable WHERE id < 12 ORDER BY ID DESC LIMIT 2

Howewer 我不能硬编码错误 ID,我怎么能做到这一点,例如结合它SELECT id FROM thetable WHERE value = 'error'或任何其他方式?

我使用 sqlite 3,但我对一切都感兴趣。

4

4 回答 4

3

我是 SQLite 的新手,所以我不知道它的语法和所有内容。但是如果它对你有用,请尝试下面的代码

select id,value
from (select *,rowid rid from tbl
order by id)
where rid in
(
  select rowid-1 from tbl
  where value = 'error'
  order by id
)or rid in
(
  select rowid-2 from tbl
  where value = 'error'
  order by id
)

演示

于 2012-09-03T11:08:36.877 回答
2

SQL 小提琴演示


我不知道 sqllite 是否具有排名功能,这会使解决方案变得更容易,但以下语句应该适用于任何符合 ANSI-92 的 DBMS。

解决方案的要点是

  • Step1:获取所有errorID
  • 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'
于 2012-09-03T10:55:57.113 回答
0
select id, value 
from test where id in (select id-1 from test where value = 'error')

如果您总是在错误后面寻找第一个 id,这将起作用。如果您可能会跳过一个 id,您可以使用 MIN 函数来获取最接近的现有 id。

于 2012-09-03T10:28:35.447 回答
0

试试这个:

SELECT id 
FROM thetable 
ORDER BY 
   CASE WHEN value = 'error' THEN value ELSE ID END
 DESC 
于 2012-09-03T10:28:46.173 回答