1

指定された値を持つ行の前に2つの行IDを取得したい。

だから私はテーブルにIDと値を持っています

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

エラーの前に2行が必要です。

ハードコーディングされたエラー行 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

ただし、エラー 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: すべてerrorの ID を取得する
  • ステップ 2: GROUP BY 句を使用してすべての ID < ルート ID を取得し、同じクエリと結合して元のエラー ID を取得する
  • ステップ 3: ステップ 2 と同様ですが、別のレベルを下ります。

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 に答える