За последние 24 часа нас посетили 18813 программистов и 1606 роботов. Сейчас ищут 885 программистов ...

Своеобразная выборка из бд

Тема в разделе "MySQL", создана пользователем kazrem, 19 мар 2013.

  1. kazrem

    kazrem Активный пользователь

    С нами с:
    19 мар 2013
    Сообщения:
    18
    Симпатии:
    1
    Всем привет! Помогите решить такой вопрос: надо вывести 4 предыдущих записей и 4 следующих записей от запрошенного id (".$_REQUEST['id']."). Решил реализовать двумя запросами к базе:
    $sql = "SELECT * FROM `table` where `cat`='$cat' and `id`>".$_REQUEST['id']." ORDER BY `id` asc LIMIT 4"; - этот выводит следующие 4 записи
    $sql = "SELECT * FROM `table` where `cat`='$cat' and `id`<".$_REQUEST['id']." ORDER BY `id` desc LIMIT 4"; - а этот соответственно 4 предыдущие.

    Все работает на ура, но только если запрошенный id не из первых или последних 4 записей, тогда один из запросов не срабатывает. То есть если запрошенный id = 3, то показывает только 2 предыдущие записи. Желаемое: Чтобы в таком случае брались 2 первых записи и 2 с конца. То есть сделать из бд некий циферблат, чтобы при любом ".$_REQUEST['id']." выводились 4 записи справа и 4 слева. Это в принципе можно реализовать?
     
  2. runcore

    runcore Старожил

    С нами с:
    12 окт 2012
    Сообщения:
    3.625
    Симпатии:
    158
    ну и в чем проблема?составляйте соответсвующие запросы и в путь
     
  3. kazrem

    kazrem Активный пользователь

    С нами с:
    19 мар 2013
    Сообщения:
    18
    Симпатии:
    1
    Проблема в том что никак не могу додуматься как составить запрос. Поэтому и решился задать вопрос.
     
  4. kazrem

    kazrem Активный пользователь

    С нами с:
    19 мар 2013
    Сообщения:
    18
    Симпатии:
    1
    Например зашел на text.php?id=2 , id доп. записей таковы 1, 3, 4, 5 и 6. А как сделать так, чтобы доп. записи были предпредпоследняя, предпоследняя, последняя, 1, 3, 4, 5 и 6?
     
  5. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    энд айди != 2
     
  6. kazrem

    kazrem Активный пользователь

    С нами с:
    19 мар 2013
    Сообщения:
    18
    Симпатии:
    1
    энд айди != 2 Не совсем понял, подскажите как прописать это

    Добавлено спустя 5 минут 4 секунды:
    Я так понял что надо так $sql = "SELECT * FROM `table` where `cat`='$cat' and `id`<".$_REQUEST['id']." and id!= 2 ORDER BY `id` desc LIMIT 4"; Но это не решает ничего, так как id2 и так не появляется в доп. записях, так что "and id!= 2" ровно ничем не помогает.
     
  7. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.131
    Симпатии:
    1.251
    Адрес:
    там-сям
    в SQL нет средств для работы с "кольцом". можете через UNION добавить запрос на получение данных с начала/конца списка. это неэффективно, но если вам очень хочется, то делайте :)
     
  8. kazrem

    kazrem Активный пользователь

    С нами с:
    19 мар 2013
    Сообщения:
    18
    Симпатии:
    1
    а как в моем случае это сделать? Мне советуют на стороне php надо логику реализовать, если недобрали запросы то добирать еще с другого конца. Вот такой подход по вашему подойдет для меня?
     
  9. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.131
    Симпатии:
    1.251
    Адрес:
    там-сям
    мне пофигу, если честно :) я не вижу в этой теме золотого зерна, за которое стоило бы бороться.
     
  10. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    да ну не так надо было. в примере 2 и я про 2 написал. вам же не только 2 нужно... и да, кольцо так просто не получится.
     
  11. kazrem

    kazrem Активный пользователь

    С нами с:
    19 мар 2013
    Сообщения:
    18
    Симпатии:
    1
    Ну так и даже в примере 2 ничего не изменилось. Так как id 2 и так не показывался. "вам же не только 2 нужно." вот именно, не знаю в каком направлении копать.
     
  12. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    а, я задачу неверно прочитал. думал вы +/- 4 делаете и вам вылезает основной идентификатор. сорри.

    ну а кольцо простым способом не организовать. выборку "основное +/-4" я бы через юнион одним запуском бы сделал.
     
  13. runcore

    runcore Старожил

    С нами с:
    12 окт 2012
    Сообщения:
    3.625
    Симпатии:
    158
    если очень хочется сделать через mysql
    то можно кактотак (прощай индексы)
    Код (Text):
    1.  
    2. -- next ids
    3. SELECT * FROM `table`
    4. where `cat`='$cat' and `id`>LEAST(".$_REQUEST['id'].", МАКСИМАЛЬНОЕ_ID-5)
    5. ORDER BY `id` asc LIMIT 4
    6.  
    7. -- prev ids
    8. SELECT * FROM `table`
    9. where `cat`='$cat' and `id`< GREATEST(".$_REQUEST['id'].", 5)
    10. ORDER BY `id` desc LIMIT 4
    но для этого нужно предварительно узнать МАКСИМАЛЬНОЕ_ID которое лежит в таблице.
     
  14. kazrem

    kazrem Активный пользователь

    С нами с:
    19 мар 2013
    Сообщения:
    18
    Симпатии:
    1
    Спасибо, будем пробовать!

    Добавлено спустя 12 минут 36 секунд:
    Код (Text):
    1. $sql = "SELECT * FROM `table` where `cat`='$cat' order by `id` desc LIMIT 1";
    2. $rs = mysql_query($sql);
    3. $data = mysql_fetch_assoc($rs);
    4. $max = $data['id'];
    Определяем МАКСИМАЛЬНОЕ_ID в заданной категории


    Код (Text):
    1. SELECT * FROM `table`
    2. where `cat`='$cat' and `id`>LEAST(".$_REQUEST['id'].", $max)
    3. ORDER BY `id` asc LIMIT 4
    Подставляем максимальный id...
    Результат разочаровал - все тоже самое, а именно зашел на text.php?id=2 , показывает только 1, 3, 4, 5 и 6.
    всего записей в бд 180
    зашел на text.php?id=179 , показывает только 175, 176, 177, 178 и 180.

    Добавлено спустя 5 минут 39 секунд:
    Ganzal,
    А можно поподробней, если на меня время не жалко...
     
  15. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    можно. если на выходе одинаковая структура данных то можно делать не Н запросов к базе, а объединить их через юнион. понимаю, что вам этого недостаточно. но вместо сообщения сюда можно было прочитать тот же мануал и потом сразу с возникшими вопросами возвращаться.
     
  16. runcore

    runcore Старожил

    С нами с:
    12 окт 2012
    Сообщения:
    3.625
    Симпатии:
    158
    Это из за вашей невнимательности.
    у меня же ясно написано что нужно не
    LEAST(".$_REQUEST['id'].", $max)
    а
    LEAST(".$_REQUEST['id'].", $max-5)

    в общем - не надо грязи - запросы рабочие 100%.
    я уже проверил даже ради вас.
     
  17. kazrem

    kazrem Активный пользователь

    С нами с:
    19 мар 2013
    Сообщения:
    18
    Симпатии:
    1
    runcore, даже моя невнимательность не помогла найти решения, поправил запрос, но опять не то - всего записей в бд 180
    зашел на text.php?id=179 , показывает 175, 176, 177, 178 (это предыдущие записи и показываются они верно), а вот со следующими записями интересней - показываются 176, 177, 178 и 179. То есть опять таки нет кольца.

    Добавлено спустя 1 минуту 55 секунд:
    это факт, но это не решает поставленного мной вопроса. И грязь я не лью, а пытаюсь найти решение.
     
  18. runcore

    runcore Старожил

    С нами с:
    12 окт 2012
    Сообщения:
    3.625
    Симпатии:
    158
    ну отнимите не 5 а 4. подберите в общем чтобы получилось кольцо)
    включите голову. я показал направление решения (вариант). ваше дело уже под себя настроить его
     
  19. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    это не запросом сделать надо а кодом
     
  20. kazrem

    kazrem Активный пользователь

    С нами с:
    19 мар 2013
    Сообщения:
    18
    Симпатии:
    1
    даже если 4 отниму, при заходе на последние 4 id в базе доп записи будут повторяться. Кольца по-любому не получится. А вот как кодом делать не знаю, это каждый раз сравнивать на остаток строк и делать циклично запрос к бд.
     
  21. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    ну не циклично, а еще один. если и там обломилось, то подходящих больше нет =)
     
  22. kazrem

    kazrem Активный пользователь

    С нами с:
    19 мар 2013
    Сообщения:
    18
    Симпатии:
    1
    igordata, Не могли бы вы примерно обрисовать, а то 2 день сижу, ничего не получается
     
  23. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    делаешь запрос в одну и вторую сторону.
    смотришь ответ по каждому.
    если ответ меньше чем 4 содержит, делаешь запрос с конца/начала
    если и он содержит меньше, то уж сколько есть. больше в базе просто нет подходящих.
     
  24. kazrem

    kazrem Активный пользователь

    С нами с:
    19 мар 2013
    Сообщения:
    18
    Симпатии:
    1
    В общем я так понял что "циферблат" из бд сделать не получится... Думаю остановиться на таком варианте: если в запросе меньше 4 строк в одном из направлений, то показываются случайные 4 записи...
     
  25. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    эм
    а что сложного сделать как я говорю?