1

以下に説明する構造を持つテーブルから前と次の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 |
+----+---------+---------------------+

テーブルは次のようにソートされます:緊急度asc、タイムスタンプasc、idasc

ソートされたテーブルは次のとおりです。

+----+---------+---------------------+
| 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 |
+----+---------+---------------------+

位置がCURRENT_ID-1またはCURRENT_ID+1であるMySQLから何かを選択する方法はありますか?

私にできることは、簡単なクエリを実行することです。

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

PHPで結果のループを作成し、適切な位置を見つけますが、これは非常に速く増加するテーブルです。だからそれは選択肢ではありません...あなたがアドバイスできる別の解決策があることを願っています

4

1 に答える 1

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

ここでSqfiddle

1 つのクエリで両方を取得しようとするのはより困難ですが、LIMIT の代わりにネストされたグループ化を使用する同様のアプローチで実行できます。このような複雑なクエリで多くのパフォーマンス上の利点が見られるとは思えず、それを維持するのは確かに困難です...

于 2013-03-21T14:32:29.760 に答える