Форум → Программирование → PHP для идиотов → Выборка информации о следующем и предыдущем элементе.
Выборка информации о следующем и предыдущем элементе.
Страницы: ← Предыдущая страница • Следующая страница →
-
7 августа 2010 г. 23:59, спустя 5 минут 49 секунд
Professor, по моему два зпроса будут быстрее, чем один, но большой. -
8 августа 2010 г. 0:11, спустя 12 минут 56 секунд
SELECT tbl.name FROM tbl WHERE tbl.id >= ALL(SELECT tbl1.id FROM tbl as tbl1 WHERE tbl1.id < {$id} LIMIT 1 ORDER BY tbl1.id ASC)
-
8 августа 2010 г. 0:19, спустя 7 минут 18 секунд
мускуль ругнулся на запрос - типо версия не поддерживает LIMIT c ALLСпустя 108 сек.Версия сервера: 5.1.47 -
8 августа 2010 г. 0:19, спустя 10 секунд
krasun, SpartakuS, вся проблемма в том что id не известен. что бы его достать нужно еще 1 запрос делать.
Или сортировать по другому полю, что плохо в моем случае. -
8 августа 2010 г. 0:31, спустя 12 минут 28 секунд
Professor, а что известно?Спустя 49 сек.
мускуль ругнулся на запрос - типо версия не поддерживает LIMIT c ALLСпустя 108 сек.Версия сервера: 5.1.47
бля, я дурак, там ALL вообще не нужен. Лимит, вернет же одну запись. -
-
8 августа 2010 г. 0:41, спустя 3 минуты 35 секунд
часть URL насколько я понял ТСSELECT tbl.name FROM tbl WHERE tbl.id >= (SELECT tbl1.id FROM tbl AS tbl1 WHERE tbl1.id < (SELECT tbl2.id FROM tbl as tbl2 WHERE tbl2.url = {$url}) LIMIT 1 ORDER BY tbl1.id ASC)
Спустя 37 сек.но мне оно не нравиться -
-
8 августа 2010 г. 0:57, спустя 12 минут 47 секунд
эх,нужны тесты. может заморочусь на днях.
Всем спасибо =) -
8 августа 2010 г. 7:43, спустя 6 часов 45 минут 30 секунд
Какая хорошая задачка!
Первое пришло в голову:
SELECT x.id
FROM mytable AS x,
(SELECT MAX(id) AS id FROM mytable WHERE id < {$id}) AS y
WHERE x.id >= y.id
ORDER BY x.id
LIMIT 3
параметр - текущий id
если мы где-то в середине таблицы, то выдаст три id-шника: {предыдущий, текущий, следующий} — бинго!
проверяем на граничные условия:
если наш id последний, выдаст {предыдущий, текущий} — хорошо
если наш id первый, выдаст {} :( — потому, что вложенный select ничего не вернул — плохо
если наш id отсутствует (удален), в зависимости от диапазона id может выдать и {} и {предыдущий, следующий, следующий за следующим} — хз
Вобщем казалось бы красиво, но не очень надежно. Надо думать дальше.
Заменяем "x.id >= y.id" на безопасный "x.id >= IFNULL( y.id, 0 )"
SELECT x.id
FROM mytable AS x,
(SELECT MAX(id) AS id FROM mytable WHERE id < {$id}) AS y
WHERE x.id >= IFNULL( y.id, 0 )
ORDER BY x.id
LIMIT 3
проверяем на граничные условия:
если наш id последний, выдаст {предыдущий, текущий} — хорошо
если наш id первый, выдаст {текущий, следующий, следующий за следующим} — хз
если наш id отсутствует (удален), в зависимости от диапазона id может выдать и {первый, второй, третий} и {последний} и {предыдущий, следующий, следующий за следующим} — хз
Если в PHP-скрипте проверять возвращаемые результаты на присутствие и позицию текущего id, то второй вариант запроса сгодится.
EXPLAIN запроса прогнозирует хорошую скорость:
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> system NULL NULL NULL NULL 1
1 PRIMARY x range PRIMARY PRIMARY 4 NULL 8 Using where; Using index
2 DERIVED NULL NULL NULL NULL NULL NULL NULL Select tables optimized awayιιlllιlllι унц-унц -
8 августа 2010 г. 8:40, спустя 57 минут 30 секунд
<?php
$id = isset($_GET['id']) ? intval($_GET['id']) : 0;
$sql = "SELECT x.id
FROM mytable AS x,
(SELECT MAX(id) AS id FROM mytable WHERE id < {$id}) AS y
WHERE x.id >= IFNULL( y.id, 0 )
ORDER BY x.id
LIMIT 3";
$dbHost = 'localhost';
$dbName = 'foo';
$dbUser = 'foo';
$dbPassword = 'bar';
$link = mysql_connect($dbHost, $dbUser, $dbPassword);
mysql_select_db($dbName, $link);
// mysql_query() фетчит сразу все записи во внутренний буфер,
// как быстро это происходит?
$time = microtime(TRUE);
$query = mysql_query($sql, $link);
$time = microtime(TRUE) - $time;
$result = array();
while ($row = mysql_fetch_assoc($query)) {
$result[] = $row['id'];
}
if (($curr = array_search($id, $result)) === FALSE) {
die('Wrong id');
}
$prev = ($curr == 0) ? NULL : $result[$curr - 1];
$next = ($curr == count($result) - 1) ? NULL : $result[$curr + 1];
$link = $_SERVER['PHP_SELF'] . '?id=';
?>
<p>
<?php if (!is_null($prev)): ?>
<a class="previous" href="<?php echo $link . $prev ?>">Previous</a> |
<?php endif; ?>
Current is <?php echo $id ?>
<?php if (!is_null($next)): ?>
| <a class="next" href="<?php echo $link . $next ?>">Next</a>
<?php endif; ?>
</p>
<p>BLABLABLA [<?php echo sprintf('%.5f', $time) ?>]</p>Спустя 253 сек.
ТЕСТ
http://test1.ru/prev_next.php?id=4
Previous | Current is 4 | Next
BLABLABLA [0.00055]
жму Previous
Current is 2 | Next
BLABLABLA [0.00054]
так и должно быть. у меня записи: {2, 4, 5, 6, …, 111}
задаю в адресной строке http://test1.ru/prev_next.php?id=111
Previous | Current is 111
BLABLABLA [0.00060]
задаю в адресной строке http://test1.ru/prev_next.php?id=112 или http://test1.ru/prev_next.php?id=3
Wrong idιιlllιlllι унц-унц -
-
8 августа 2010 г. 10:18, спустя 1 час 10 минут 9 секунд
это непринципиально. считай что url это id. урлы ведь уникальны?
если не уникальны, то задача некорректная. в таком случае нельзя вычислить "предыдущий" и "следующи"Спустя 277 сек.как мне кажется, ТС тупанул и поместил в свою таблицу url уже как результат размышлений :) урл — это производная от какого-то идентификатора. обычно так. зачем хранить сам урл?Спустя 151 сек.хотя непринципиально. все операции типа max(), "<", ">=", "order by" будут работать и для текстового поля. надеюсь поле уникально проиндексированоιιlllιlllι унц-унц -
8 августа 2010 г. 10:29, спустя 11 минут 49 секунд
ТС еще не уточнил - только ли айдишники ему нужны в выборкеСпустя 42 сек.artoodetoo,
вероятно самое краткое решение из приведенных :) -
Страницы: ← Предыдущая страница • Следующая страница →
Пожалуйста, авторизуйтесь, чтобы написать комментарий!