Получить предыдущую и следующую запись из базы данных и зациклить их - PullRequest
0 голосов
/ 20 мая 2019

У меня есть таблица с идентификаторами от 1 до 8. Я хочу что-то вроде этого

Если я на 4, я должен получить 3,5

Если я 'м в 1, я должен получить 8,2

Если в 8, я должен получить 7, 1

В основном циклический просмотр таблицы записей

Этомой текущий код

-- previous or last, if there is no previous
SELECT *
FROM news
WHERE id < 1 OR id = MAX(id)
ORDER BY id DESC
LIMIT 1

-- next or first, if there is no next
SELECT *
FROM news
WHERE id > 1 OR id = MIN(id)
ORDER BY id ASC
LIMIT 1

Но там написано Неправильное использование групповой функции .Любая помощь?

Ответы [ 3 ]

1 голос
/ 20 мая 2019

Я предполагаю, что вы хотите показывать кнопки «предыдущий» и «следующий», когда пользователь просматривает новостную статью. Я бы получил предыдущий и следующий идентификатор в основном запросе, когда вы выбираете данные статьи:

select n.*, -- select columns you need
  coalesce(
    (select max(n1.id) from news n1 where n1.id < n.id ),
    (select max(id) from news)
  ) as prev_id,
  coalesce(
    (select min(n1.id) from news n1 where n1.id > n.id ),
    (select min(id) from news)
  ) as next_id
from news n
where n.id = ?

ДБ-Fiddle демо

Теперь вы можете использовать prev_id и next_id для своих кнопок или предварительно выбрать соответствующие статьи простым запросом select * from news where id = ?.

1 голос
/ 20 мая 2019

Если идентификатор последовательный, вы можете сделать это:

SQL DEMO

SELECT o.id, 
       COALESCE(b.id, (SELECT MAX(ID) FROM Table1)) as before_id,
       COALESCE(a.id, (SELECT MIN(ID) FROM Table1)) as after_id
FROM Table1 o
LEFT JOIN Table1 b
  ON o.id = b.id + 1
LEFT JOIN Table1 a  
  ON o.id = a.id - 1
ORDER BY o.id  

OUTPUT

| id | before_id | after_id |
|----|-----------|----------|
|  1 |         8 |        2 |
|  2 |         1 |        3 |
|  3 |         2 |        4 |
|  4 |         3 |        5 |
|  5 |         4 |        6 |
|  6 |         5 |        7 |
|  7 |         6 |        8 |
|  8 |         7 |        1 |

Если идентификаторы не последовательные, вам нужно использовать row_number() (mysql ver 8+) или переменные сеанса для создания последовательности.

0 голосов
/ 20 мая 2019

Вы можете удалить фильтрацию в своем подходе и добавить логику к ORDER BY:

(SELECT n.*
 FROM news
 ORDER BY (id < 1), id DESC
 LIMIT 1
) UNION ALL
(SELECT n.*
 FROM news
 ORDER BY (id > 1), id ASC
 LIMIT 1
) ;

Если вы хотите, чтобы значения id находились в одной строке, вы можете использовать агрегирование:

select coalesce(max(case when id < 1 then id end), max(id)) as prev_id,
       coalesce(min(case when id > 1 then id end), min(id)) as next_id
from news n;

В обоих случаях 1 - это идентификатор образца, а «1» можно заменить любым значением.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...