2016-09-13 86 views
1

我想選擇與我的表中的id列表相匹配的所有行,其中包括之前的2行和之後的2行。按ID排序。爲ID列表包含多個周圍的行(按ID排序)

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 

現在我已經查詢:

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

如何延長它也返回編號3,4,6,7日和12,13,17,19?我不知道確切的ID。表格中可能存在空白。如果5不匹配,則不應退回3,4,6和7。

我已經閱讀了有關「周圍行」的所有其他問題。但他們都處理一個結果,應該包括周圍的行。

+0

如果例如5個不在表格中,但是6和7是什麼?你還想要退回嗎? – Mureinik

+0

您可以爲每行分配一個等級(有效消除間隙需求),然後連接兩個等級內的行 - 螺母mureiniks問題有效;如果目標行丟失,您是否還想要返回相鄰行 – 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 

上面的查詢使用變量兩次:第一次行號分配給每個記錄,第二次以過濾周圍的記錄。

Demo here

+0

我認爲sql服務器將使用此版本在內存中創建一個完整的表副本。我的表格最多可以有10.000.000行。我是我必須引入一個'索引'欄來避免這個副本。但是,刪除一行時,速度很慢。 – SuperNova

+0

@SuperNova不幸的是,MySQL不支持窗口函數,所以沒有簡單的方法來實現這樣的查詢。您是否使用實際數據嘗試了這個查詢? –

+1

升級到MariaDB 10.2並使用其窗口功能。他們非常適合這樣的查詢。 –