2013-03-21 71 views
1

排序沒有提到下面如何從表以前&下一個ID具有結構:獲取前行標識,而在ID

+----+---------+---------------------+ 
| id | urgency | timestamp   | 
+----+---------+---------------------+ 
| 1 | 0  | 2013-01-01 00:00:00 | 
| 2 | 2  | 2013-01-01 00:00:00 | 
| 3 | 1  | 2013-01-05 09:30:00 | 
| 4 | 2  | 2013-01-01 00:00:00 | 
| 5 | 2  | 2013-01-01 00:00:00 | 
| 6 | 1  | 2013-01-06 10:00:00 | 
| 7 | 0  | 2013-01-01 00:00:00 | 
| 8 | 0  | 2013-01-03 00:00:00 | 
| 9 | 1  | 2013-02-01 13:30:00 | 
| 10 | 0  | 2013-01-04 00:00:00 | 
+----+---------+---------------------+ 

表進行排序如下:尿急遞增,時間戳遞增, ID ASC

這裏是排序表:

+----+---------+---------------------+ 
| id | urgency | timestamp   | 
+----+---------+---------------------+ 
| 1 | 0  | 2013-01-01 00:00:00 | 
| 7 | 0  | 2013-01-01 00:00:00 | 
| 8 | 0  | 2013-01-03 00:00:00 | 
| 10 | 0  | 2013-01-04 00:00:00 | 
| 3 | 1  | 2013-01-05 09:30:00 | 
| 6 | 1  | 2013-01-06 10:00:00 | 
| 9 | 1  | 2013-02-01 13:30:00 | <= CURRENT_ID 
| 2 | 2  | 2013-01-01 00:00:00 | 
| 4 | 2  | 2013-01-01 00:00:00 | 
| 5 | 2  | 2013-01-01 00:00:00 | 
+----+---------+---------------------+ 

有沒有辦法從MySQL選擇一些地方的位置CURRENT_ID - 1或CURRENT_ID + 1?

我能做的是執行一個簡單的查詢:

SELECT 
    id 
FROM 
    MY_TABLE 
ORDER BY 
    urgency asc, 
    timestamp asc, 
    id asc 

通過創建結果PHP一個循環,並尋找合適的位置,但是這是一個表,將會增加非常快。因此,這不是一個選項...希望有另一種解決方案,您可以建議

+0

我懷疑這是可能的。只是緩存數據可能會有更多的運氣。 – 2013-03-21 14:32:08

+0

我不明白 - 在你的例子中,你想找到id = 6或2? – 2013-03-21 14:46:35

+0

@傑克,它當然是可能的,看到這[sqlfiddle](http://www.sqlfiddle.com/#!2/08ab1/1) – PinnyM 2013-03-21 14:49:19

回答

3

對於以前:

SELECT prev.id 
FROM my_table current 
JOIN my_table prev 
    ON (prev.urgency < current.urgency) 
    OR (prev.urgency = current.urgency 
     AND (prev.timestamp < current.timestamp 
      OR (prev.timestamp = current.timestamp AND prev.id < current.id))) 
WHERE current.id = @currentId 
ORDER BY prev.urgency desc, prev.timestamp desc, prev.id desc 
LIMIT 1 

對於未來:

SELECT next.id 
FROM my_table current 
JOIN my_table next 
    ON (next.urgency > current.urgency) 
    OR (next.urgency = current.urgency 
     AND (next.timestamp > current.timestamp 
      OR (next.timestamp = current.timestamp AND next.id > current.id))) 
WHERE current.id = @currentId 
ORDER BY next.urgency asc, next.timestamp asc, next.id asc 
LIMIT 1 

Sqlfiddle這裏。

試圖讓它們在一個查詢中更具挑戰性,但可以使用類似的方法使用嵌套分組代替LIMIT來完成。我懷疑你會在這樣一個複雜的查詢中看到很多性能優勢,你肯定會很難保持它...

+0

工作得很好!謝謝! – AndVla 2013-03-21 14:57:00

+0

@PinnyM「prev」查詢不適用於current.id = 1 – 2013-08-14 08:04:56