2016-09-13 5 views
1

私はテーブルのIDリストと一致するすべての行を、前2行と後2行を含むテーブルから選択したい。 idによってオーダーされます。IDのリストのために複数の周囲の行を含める(ID順)

SELECT `ID`, `Value` FROM `table` WHERE `ID` in (5, 14) ORDER BY `ID`; 

は、どのように私はそれがまたIDが3、4、6、7、12、13、17、19返すように拡張することができます。

ID | Value 
---+---------- 
    1 | Value #1 
    2 | Value #2 
    3 | Value #3 
    4 | Value #4 
    5 | Value #5 
    6 | Value #6 
    7 | Value #7 
    8 | Value #8 
    9 | Value #9 
10 | Value #10 
11 | Value #11 
12 | Value #12 
13 | Value #13 
14 | Value #14 
17 | Value #17 
19 | Value #19 
20 | Value #20 
28 | Value #28 
29 | Value #29 
30 | Value #30 

今、私は、クエリをしましたか?私は正確なIDを知らない。テーブルに隙間があるかもしれません。 5が一致しない場合は、3、4、6、7を返さないでください。

私はすでに「周囲の行」に関する他のすべての質問を読んでいます。しかし、彼らはすべて、周囲の行を含める必要がある1つの結果を処理しています。

+0

たとえば、5がテーブルになく6と7の場合はどうなりますか?あなたはまだそれらを戻したいですか? – Mureinik

+0

各行にランクを割り当てることができます(ギャップの必要性を実質的に排除します)。次に、ランク2以内の行に参加します。ターゲット行が見つからない場合でも隣接する行が返されるようにしますか? – Strawberry

+0

5が一致しない場合は、3、4、6および7が返されません。 – SuperNova

答えて

0

次のクエリを使用することができます。

SELECT ID, Value 
FROM (
    SELECT ID, Value, 
      @rn1 := @rn1 + 1 AS rn 
    FROM mytable 
    CROSS JOIN (SELECT @rn1 := 0) AS v 
    ORDER BY ID) AS t1 
JOIN (
    SELECT rn 
    FROM (
     SELECT ID, Value, 
      @rn := @rn + 1 AS rn 
     FROM mytable 
     CROSS JOIN (SELECT @rn := 0) AS v 
     ORDER BY ID) AS t 
    WHERE t.ID IN (5, 14) 
) AS t2 ON t1.rn BETWEEN t2.rn - 2 AND t2.rn + 2 

上記のクエリは、二回の変数を使用する:一度周囲のレコードをフィルタするために、各レコードおよび第2の時間に行番号を割り当てます。

Demo here

+0

私は、SQL Serverがこのバージョンを使用してメモリにフルテーブルコピーを作成すると思います。私のテーブルは10.000.000までの行を持つことができます。私はいつもそのコピーを避けるために 'Index'カラムを導入しなければなりません。しかし、それは行を削除するときには遅いです。 – SuperNova

+0

@ SuperNova残念ながら、MySQLはウィンドウ関数をサポートしていないので、そのようなクエリを簡単に実装する方法はありません。実際のデータでこのクエリを試しましたか? –

+1

MariaDB 10.2にアップグレードし、Windowing機能を使用します。そのようなクエリには優れています。 –

関連する問題