За последние 24 часа нас посетили 18254 программиста и 1637 роботов. Сейчас ищет 1571 программист ...

Выбор трех записей - текущей, предыдущей и следующей

Тема в разделе "PHP и базы данных", создана пользователем aswind, 17 ноя 2009.

  1. aswind

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

    С нами с:
    5 окт 2009
    Сообщения:
    27
    Симпатии:
    0
    Всем привет! Собственно суть проблемы описана в названии темы - не могу додуматься как выбрать из БД три записи.
    Ситуация такая: есть фотоальбом самописный, нужно реализовать ссылки "предыдущее фото" и "следующее фото". Не могу понять как...
    Структура БД такая:
    owner - ID владельца
    album - ID альбома
    filename - имя файла (без .jpg, сгенерированное md5(rand()))
    GET-ом передаются все три этих свойства.
    Я почти уверен, что в языке SQL есть какой-либо оператор, делающий это :) Поиск в гугле ничего не дал - все что есть не подходит, т.к. нет привязки по ID (только хеш) и надо учитывать, что предыдущим снимком может владеть другой пользователь.
    Надеюсь на вашу помощь, всем спасибо!
     
  2. ideea

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

    С нами с:
    3 окт 2009
    Сообщения:
    60
    Симпатии:
    0
    создай таблицу photos, где все фотки и ID альбомов
     
  3. Apple

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

    С нами с:
    13 янв 2007
    Сообщения:
    4.984
    Симпатии:
    2
    А если удалить фотку? =)
    Будут пробелы в ID, в результате +/- 1 могут не существовать.
     
  4. Padaboo

    Padaboo Старожил
    Команда форума Модератор

    С нами с:
    26 окт 2009
    Сообщения:
    5.242
    Симпатии:
    1
    мб при удалении update все id?
     
  5. aswind

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

    С нами с:
    5 окт 2009
    Сообщения:
    27
    Симпатии:
    0
    В общем, до решения допер сам. Добавил поле id auto_increment
    [sql]SELECT `filename` FROM `pics_items` WHERE `id`>[ID] AND `owner`=[USER_ID] AND `album`=[ALBUM_ID] ORDER BY `id` ASC LIMIT 1[/sql]
     
  6. armadillo

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

    С нами с:
    6 апр 2007
    Сообщения:
    2.380
    Симпатии:
    0
    Адрес:
    Russia, Moscow
    это и предыдущая и следующая?
     
  7. aswind

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

    С нами с:
    5 окт 2009
    Сообщения:
    27
    Симпатии:
    0
    нет, только одна из них
     
  8. ideea

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

    С нами с:
    3 окт 2009
    Сообщения:
    60
    Симпатии:
    0
    PHP:
    1. Будут пробелы в ID, в результате +/- 1 могут не существовать.
    Есть next, prev функции.
    http://lv.php.net/manual/en/function.next.php
    http://lv.php.net/manual/en/function.prev.php
    Или такой способ, тупой конечно, года полтора назад делал так.
    PHP:
    1.  
    2. <?php
    3. $getCnt = $db->query("SELECT * FROM `admin_users` WHERE (`level` = 1 || `level` = 2) && `visible`=1 ORDER BY id ASC");
    4.     $cnt = mysql_fetch_assoc($getCnt);
    5.     $i = 1;
    6.     $arrayPlace = array();
    7.     reset($arrayPlace);
    8.     $arrayPlace[0] = $cnt['id'];
    9.     while($row = mysql_fetch_assoc($getCnt)) {
    10.         $arrayPlace[$i] = $row['id'];
    11.         $i++;
    12.     }
    13.  
    14.     $key = array_search($_GET['pid'], $arrayPlace);
    15. ?>
    16. <?php if($_GET['pid'] == end($arrayPlace)): ?>
    17.                 <a href="javascript:void(0);" id="disable"><?= $LNnext ?></a>
    18.             <?php else: ?>
    19.                 <a href="<?= SITE ?>/profile/<?= ($arrayPlace[$key+1]) ?>/"><?= $LNnext ?></a>
    20.             <?php endif ?>
    21.    
     
  9. Volt(220)

    Volt(220) Активный пользователь

    С нами с:
    11 июн 2009
    Сообщения:
    1.640
    Симпатии:
    1
    По аналогии:

    [sql]SELECT `filename` FROM `pics_items` WHERE `id`>[ID] AND `owner`=[USER_ID] AND `album`=[ALBUM_ID] ORDER BY `id` ASC LIMIT 1
    union
    SELECT `filename` FROM `pics_items` WHERE `id`<[ID] AND `owner`=[USER_ID] AND `album`=[ALBUM_ID] ORDER BY `id` desc LIMIT 1[/sql]
     
  10. aswind

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

    С нами с:
    5 окт 2009
    Сообщения:
    27
    Симпатии:
    0
    Volt(220)
    Неа. Т.к. айди присваивается AUTO_INCEREMENT'ом, а он не смотрит кто был владельцем 640 снимка, а кто 1250. А владелец один. И что делать? :)
     
  11. Simpliest

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

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    Подумать

    Ты же выбираешь диапазон. Значит при выборке ты знаешь номер этого диапазона и можешь вычислить номер предыдущего и номер следующего.

    Считай что у тебя постраничная навигация всего с 1ной фото на странице.

    А оператор LIMIT, нужно только правильно им воспользоваться
     
  12. MiksIr

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

    С нами с:
    29 ноя 2006
    Сообщения:
    2.339
    Симпатии:
    44
    Классическая задачка. А значит можно гуглить. В самом простом случае и правда можно обойтись 3-я запросами: 1 на выборку данных по текущей фото и два запроса с <> на выборку следующего и предыдущего. Погуглив, можно найти и даже как обойтись одним запросом, например:
    Код (Text):
    1. SELECT test.*, next.id AS next_id, prev.id AS prev_id FROM test
    2.   FULL OUTER JOIN test AS next ON (next.id>test.id)
    3.   FULL OUTER JOIN test AS prev ON (prev.id<test.id)
    4.   WHERE test.id=<ваш id> ORDER BY next_id ASC, prev_id DESC LIMIT 1;
     
  13. Volt(220)

    Volt(220) Активный пользователь

    С нами с:
    11 июн 2009
    Сообщения:
    1.640
    Симпатии:
    1
    aswind
    А в чем проблема?
    Первый запрос возвращает следующую фотку, второй - предыдущую. Только надо добавить к результатам выборки константу, чтобы в случае ненахождения одной из фоток определить какую таки нашли.
     
  14. Simpliest

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

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    Одним! :) без JOIN :)
     
  15. MiksIr

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

    С нами с:
    29 ноя 2006
    Сообщения:
    2.339
    Симпатии:
    44
    Simpliest, давай пример
    Код (Text):
    1. id
    2. ___
    3. 12
    4. 34
    5. 46
    6. 74
    7. 99
    Дано id=46, нужно - выбрать предыдущий и следующий id.
     
  16. Simpliest

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

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    MiksIr чуток внимательнее читаем :)
    и не усложняем себе задачу кривой базой :)
    Так что нам дано целых 3х разных ID :) из которых нам надо только два :)
     
  17. MiksIr

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

    С нами с:
    29 ноя 2006
    Сообщения:
    2.339
    Симпатии:
    44
    Simpliest, так вот если внимательнее читать - то человек уже догадался ввести id записи, ибо без онного задача в принципе не решаемая, так как нет критерия сортировки.
     
  18. Simpliest

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

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    MiksIr
    Не пугай меня.

    Мы смотрим не просто картинку! Мы смотрим фото из конкретной последовательности!
    И id фото в этой последовательности нам даром не нужен. Нам нужны остальные параметры - альбом, владелец и т.д.

    Выбрать картинку по ее порядковому номеру (не по ID) и соответственно следующую/предыдущую, я надеюсь не сотавит труда?
     
  19. Simpliest

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

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    И, да, в данном случае он нахрен не нужен.
    Ибо картинка однозначно идентифицируется по ID-автора + ID-альбома +md5(rand()))

    Более того!
    md5(rand())) - это фактически UID
     
  20. MiksIr

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

    С нами с:
    29 ноя 2006
    Сообщения:
    2.339
    Симпатии:
    44
    Simpliest
    1. Термин "конкретная последовательность" является не определенным без критериев сортировки.
    2. Подумайте, пожалуйста, про себя, почему ссылка на картинку всегда дается по ее идентификатору, а не по "порядковому номеру в конкретной последовательности".

    aswind
    Реально я бы предложил 2 варианта. Первый - поддержание нумерации без дырок - это будет поле сортировки, которое позволит в дальнейшем дать пользователю возможность менять свои фотки местами. Второй вы и сами нашли, единственное мое предложение - выводя фото не ищите сразу следующий и предыдущий id. Лучше делайте сыылки вида /?id=текущее_фото&show=next, по такому запросу ищите в базе id следующей фото и выдавайте редирект header("Location: ... /?id=новое_id").
     
  21. Simpliest

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

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    Да? Просветил.
    А термины следующая/предыдущая - являются определенными без критериев сортировки?
    Гонишь?

    Мы не ссылку на картинку берем. А формируем viewstate для скрипта!
    В честь чего вдруг всегда по ее идентификатору?
    Блин, не тупи!

    Если мы отдаем статическую картинку - то нам нужен ее URI. Если мы хотим ссылку на следующую/предыдущую из списка, то мы работаем со скриптом. А значит нам нужен порядковый номер текущей картинки и условие выборки списка. Все.

    [sql]SELECT `filename` FROM `pics_items` WHERE `owner`=[USER_ID] AND `album`=[ALBUM_ID] ORDER BY `filename` ASC LIMIT [pageN], 1[/sql]
    [pageN] - порядковый номер просматриваемой картинки
    `owner`=[USER_ID] AND `album`=[ALBUM_ID] - условие выборки.

    Имя картинки мы получили без ID

    Еще вопросы?
     
  22. MiksIr

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

    С нами с:
    29 ноя 2006
    Сообщения:
    2.339
    Симпатии:
    44
    Да, есть еще вопрос - как долго друзья этого [USER_ID] будут видеть именно ту страницу с картинкой, на которую им прислали ссылку... а не совершенно какую-то другую.
     
  23. Simpliest

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

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    Ровно до тех пор пока не изменится результат выборки. А в данном конкретном альбоме данного конкретного пользователя это произойдет тогда, когда он удалит картинку :)

    А ссылка на страницу с ЭТОЙ картинкой будет выглядеть иначе, чем ссылка на картинку ИЗ ЭТОЙ выборки :)
    Это разные вещи.

    Не копай - не подкопаешься. ID там нахрен не нужен. И геморрой с нумерацией без дырок тоже.

    Можно ввести timestamp как время добавления картинки и сортировать по нему. Это всеравно нужно в альбоме и убьет твои поползновения на корню :)
     
  24. MiksIr

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

    С нами с:
    29 ноя 2006
    Сообщения:
    2.339
    Симпатии:
    44
    Ты вообще когда-нибудь галерею видел? Есть альбом и в нем фотографии. И ссылку дают на страницу с фото. Нормальному человеку в голову не придет, что URL страницы и картинка на самом деле не связаны и стоит ему что-то изменить - все поменяется.
    Именно по-этому подходы в формировании страниц в галерее и в выводе страницы с одной фото - разные. Так что даже копать не буду - думайте чаще, тренируйтесь.
     
  25. Simpliest

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

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    Нет. Подходы разные по причине глупости отдельных разработчиков :)

    А читаешь ты невнимательно

    timestamp+filename+userid+albumid = uid
    Порядковый номер изменится только в одном случае - удалении картинки :)

    При этом твоя ссылка станет тупо нерабочей. А у меня выдаст результат.

    Молодец - аутотренинг это хорошо :) а то ты совсем обленился - перестал думать :)