Я работаю над приложением Oracle/PHP и пытаюсь реализовать функциональность "load-more".
Вот две таблицы и их структуры:
questions:
id (int) | title (varchar(999)) | datetime (varchar(999))
id (int) | title (varchar(999)) | datetime (varchar(999))
questions_tags:
id (int) | question_id (int) | tag_id (int)
id (int) | question_id (int) | tag_id (int)
Ниже приведен код в index.php:
$stid = oci_parse($conn, "select * from (
select a.*, ROWNUM rnum from (
SELECT questions.id FROM questions_tags, questions WHERE
questions.id = questions_tags.question_id AND
questions_tags.tag_id IN (1,2,3,4,5,6,7) ORDER BY questions.datetime ASC
) a where rownum <= 10
) where rnum >= 0");
oci_execute($stid);
while (oci_fetch($stid)) {
// Do work with the results
}
Ниже приведен javascript:
$("#load_more").click(function(e) {
$.ajax({
url: "loadMore.php?x=" + $(".span_data:last").data("id"),
success:function(data, textStatus, jqXHR)
{
if (data)
{
// append data
} else {
// remove button
}
},
error: function(jqXHR, textStatus, errorThrown)
{
//if fails
}
});
e.preventDefault(); //STOP default action
});
Наконец, вот файл loadMore.php:
<?php
$x = $_GET['x'];
$xTen = intval($x) + 10;
$count_id = $x;
try
{
$lastID = 0;
$tagIDs = implode("','", $user_tag_ids);
$stid = oci_parse($conn, "select * from (
select a.*, ROWNUM rnum from (
SELECT questions.id FROM questions_tags, questions WHERE
questions.id = questions_tags.question_id AND
questions_tags.tag_id IN (1,2,3,4,5,6,7) ORDER by questions.datetime DESC
) a where rownum <= $xTen
) where rnum >= $x");
oci_execute($stid);
while (oci_fetch($stid)) {
// Do work with the results
}
}
catch(Exception $e) {
print "Error";
}
?>
Независимо от значения x
, файл loadMore.php
продолжает возвращать тот же набор результатов. Поэтому, если я сделаю /loadMore.php?x=10
, я получу те же результаты, что и возвращенные /loadMore.php?x=100
Однако, если я пойду еще дальше (/loadMore.php?x=1500
), это когда я наконец получаю разные результаты. Я не могу понять, что здесь происходит.
Как я уже сказал в комментариях:
Если я удалю все параметры rownum
и просто запустил
SELECT * FROM questions WHERE EXISTS (
SELECT 1 FROM questions_tags WHERE
questions.id = questions_tags.question_id AND
questions_tags.tag_id IN (1,2,3,4,5,6,7)
) ORDER BY datetime DESC
Я получаю все результаты, возможно, тысячу строк. Я пытаюсь получить первые 10 из этих тысяч строк, а затем продолжаю получать следующие 10, когда пользователь нажимает кнопку "загрузить больше". Вот почему у меня одинаковые запросы index.php и loadMore.php
Благодаря комментариям я понял, что ORDER BY questions.datetime
не был достаточно уникальным, чтобы правильно отсортировать результат. Изменив запрос на ORDER BY questions.datetime DESC, questions.id DESC
исправил проблему и начал показывать уникальные результаты.
questions.datetime
уникальным? Если вашORDER BY
не создает уникальный порядок, вполне возможно, что строка получит другойROWNUM
при последующих выполнениях даже с теми же параметрами. Другими словами, если «первые 10» не определены четко, потому что есть сотни строк с одинаковым значениемdatetime
, ваш подход не будет работать хорошо.datetime
не уникален. Если я удаляю все параметры rownum и просто запускаюSELECT * FROM questions WHERE EXISTS (SELECT 1 FROM questions_tags WHERE questions.id = questions_tags.question_id AND questions_tags.tag_id IN ('$tagIDs'))ORDER BY datetime DESC
запрос, я получаю все результаты, вероятно, тысячи строк. То, что я в значительной степени пытаюсь сделать, это получить первые 10 из этих тысяч строк, а затем продолжать получать следующие 10, когда пользователь нажимает кнопку «загрузить еще». Вот почему у меня есть тот же запросindex.php
иloadMore.php