2015-01-02 4 views
0

На странице для просмотра сообщений я подумал, что было бы неплохо иметь ссылки для следующих и предыдущих сообщений. Я думал, что должен получить эти 3 записи в 1 запросе, так как я такой умный, и у меня было кучу времени, чтобы тратить все равно. Так что, как вы, наверное, догадались, я не мог этого сделать, но мне интересно найти решение. Вот что у меня естьВыберите предыдущие и следующие записи в заявлении о присоединении

SELECT a.id, 
     a.title, 
     a.body, 
     p.id AS prev_id, 
     p.title AS prev_title, 
     n.id AS next_id, 
     n.title AS next_title 
FROM posts a 
     LEFT JOIN posts p 
       ON p.id < a.id 
     LEFT JOIN posts n 
       ON n.id > a.id 
WHERE a.id = ? 
LIMIT 1 

Проблема заключается в том, что для prev_id и prev_title я всегда получаю первый запись в таблице. Я попытался добавить ORDER BY, но на самом деле это не повлияло на соединение. Как я могу выбрать предыдущую, а не первую запись, используя соединение, как в примере?

+0

мы можем предположить, что p.id является последовательный, и когда вы говорите следующее/предыдущее, это следующий использованный идентификатор? поэтому в предыдущем это был бы MAX ID до (<) P.Id, а для N это был бы MIN (ID) после (>) P.ID? Или вы говорите следующую статью в группе, которая может не иметь ничего общего с идентификаторами ... примеры данных структуры таблицы и/или SQLFiddle помогли бы; поскольку ответ зависит от вашей структуры таблицы и используемых данных. – xQbert

+0

@xQbert Нет, это довольно простая таблица, и все, кроме я не хочу жестко кодировать 'a.id - 1' и' a.id + 1' для prev и next, потому что некоторые сообщения могут удаляться и могут возникать пробелы –

+0

Хотя , «следующий» и «предыдущий» полезны для «нас» как людей. Что касается SQL, у него действительно нет понятия «упорядоченного набора (списка)», то есть «выход» процесса обработки вашего запроса. SQL-запросы «знают» о «наборах», которые, к сожалению, не «упорядочены». –

ответ

1

Я надеюсь, что это одна может оказаться полезной:

SELECT a.id, 
     a.title, 
     a.body, 
     p.id AS prev_id, 
     p.title AS prev_title, 
     n.id AS next_id, 
     n.title AS next_title 
FROM posts a 
     INNER JOIN 
     (
      SELECT 
       _a.id AS RefID, 
       MIN(_a.id - _p.id) AS MinDistPrev, 
       MIN(_n.id - _a.id) AS MinDistNext 
      FROM 
       posts _a 
       LEFT JOIN posts _p 
         ON _p.id < _a.id 
       LEFT JOIN posts _n 
         ON _n.id > _a.id 
      WHERE 
       _a.id = ? 
      GROUP BY 
       _a.id 
     ) AS _PrevNextDist 
     ON _PrevNextDist.RefID = a.ID 
     LEFT JOIN posts p 
       ON p.id < a.id 
       AND a.id - p.id = _PrevNextDist.MinDistPrev 
     LEFT JOIN posts n 
       ON n.id > a.id 
       AND n.id - a.id = _PrevNextDist.MinDistNext 
LIMIT 1 

Кроме, добавление ORDER BY p.id DESC к исходному коду решить эту проблему, а

SELECT a.id, 
     a.title, 
     a.body, 
     p.id AS prev_id, 
     p.title AS prev_title, 
     n.id AS next_id, 
     n.title AS next_title 
FROM posts a 
     LEFT JOIN posts p 
       ON p.id < a.id 
     LEFT JOIN posts n 
       ON n.id > a.id 
WHERE a.id = ? 
ORDER BY p.id DESC 
LIMIT 1 
+0

Извините, я только что отредактировал ответ - было 2 ошибки - теперь все должно быть в порядке. –

+0

whoaa! Я все еще получаю сообщение об ошибке. Это кажется более сложным, чем я ожидал. Разве вы не думаете, что мне было бы лучше запустить еще два запроса, а не иметь такую ​​логику в sql? Спасибо за попытку! –

+0

Нет проблем, запрос должен быть ОК только сейчас, если вы можете проверить его снова - орфографические ошибки в коде. Извините, пытался писать слишком быстро :) –

Смежные вопросы