mysql заявка

venco

New member
Здравейте,
Имам галерия със снимки на потребители. Структурата на таблицата със снимките е следната: pic_id, user_id, picture, ....
Как мога в ЕДНА mysql заявка без вложени селекти да взема pic_id-то на снимката, pic_id-то на предходната снимка и pic_id-то на следващата снимка на даден потребител или с други думи долните три заявки да станат в една:

$user_id=100; // id на потребителя
$id=5; // id на снимката

//снимка
$q=mysql_query("SELECT pic_id,picture FROM pictures WHERE pic_id='$id' AND user_id='$user_id'");

//предходна снимка
$q_prev=mysql_query("SELECT pic_id,picture FROM pictures WHERE pic_id<'$id' AND user_id='$user_id'" ORDER BY pic_id DESC LIMIT 1);

//следваща снимка
$q_next=mysql_query("SELECT pic_id,picture FROM pictures WHERE pic_id>'$id' AND user_id='$user_id' ORDER BY pic_id ASC LIMIT 1");



нещо подобно само че това не работи:
$q= mysql_query("SELECT pic_id,picture FROM pictures WHERE (pic_id='$id' OR pic_id>'$id' OR pic_id<'$id' ) AND user_id='$user_id' LIMIT 3 ");

Благодаря Ви предварително!
 
Последно редактирано:
Re: mysql заявка

$id1=$id-1;
$id2=$id+1

"SELECT pic_id,picture FROM pictures WHERE pic_id in ('$id','$id1','$id2') AND user_id='$user_id'"
 
Re: mysql заявка

Това горното важи само ако презумпцията е, че pic_id си вървят все подред и няма изтриване на редове. Иначе става злобно.

Всъщност както е зададен въпроса, си е така.
Ако беше зададен от рода на "Как да взема pic_id и първата най-близка предходна стойност и първата най-близка следваща стойност ?" става друго.
 
Re: mysql заявка

@Kompota точно това питам и аз 🙂

@krapo а ако има изтрити записи? 🙂
 
Re: mysql заявка

http://www.w3schools.com/sql/sql_between.asp

Иначе, варианта на krapo е по-добър ако знаеш точните краен брой айдита.

Viktor незнам точния брой записи а и да го знам не виждам какво ще ми помогне 🙂 Ако можеш да ми дадеш пример как става това с IN, ще съм ти благодарен.

ПП. Доколкото знам в база с голям брой записи препоръчват да не се използва IN.
 
Последно редактирано:
Re: mysql заявка

Ако има изтрити записи от таблицата, то няма по-бърз начин от три заявки.

Реално проблем в горните заявки е, че не си добавил ORDER и LIMIT 1 😉
Ако го добавиш ще се изпълняват достатъчно бързо, защото ти в момента взимаш цялата таблица преди или сред това ID, което може да са хиляди/милиони редове!
 
Re: mysql заявка

@mlazarov да вярно че съм забравил LIMIT и ORDER (сега видях като ми каза). Но принципно има ли начин да се направи това в една заявка?
 
Re: mysql заявка

@mlazarov да вярно че съм забравил LIMIT и ORDER (сега видях като ми каза). Но принципно има ли начин да се направи това в една заявка?

Има, но не и без join.
Може и с union.
 
Re: mysql заявка

Пробвай нещо подобно (не съм го тествал, но би трябвало да стане):

select pic_id from pictures

where pic_id>ifnull((select max(pic_id) from pic WHERE pic_id<'$id' AND user_id='$user_id'), 0) and user_id='$user_id'

order by pic_id asc

limit 3
 
Re: mysql заявка

можеш да го направиш с един селект, да ти върне id-тата на снимките, да ги вкараш в array и после да вземеш предишно и следващо id, като знаеш текущото

ето пример

PHP:
echo "<hr><pre>";
$array = array(1, 5, 6, 7, 8, 10, 16, 734, 773);
print_r($array);
// търсен елемент
$srch = array_search('16', $array); 

function getPrevNext($haystack,$needle) {
    $prev = $next = null;

    $aKeys = array_keys($haystack);
    $k = array_search($needle,$aKeys);
    if ($k !== false) {
        if ($k > 0)
            $prev = array($aKeys[$k-1] => $haystack[$aKeys[$k-1]]);
        if ($k < count($aKeys)-1)
            $next = array($aKeys[$k+1] => $haystack[$aKeys[$k+1]]);
    }
    return array($prev,$next);
}

print_r(getPrevNext($array,$srch));

echo "</pre><hr>";
 
Re: mysql заявка

можеш да го направиш с един селект, да ти върне id-тата на снимките, да ги вкараш в array и после да вземеш предишно и следващо id, като знаеш текущото

ето пример

PHP:
echo "<hr><pre>";
$array = array(1, 5, 6, 7, 8, 10, 16, 734, 773);
print_r($array);
// търсен елемент
$srch = array_search('16', $array); 

function getPrevNext($haystack,$needle) {
    $prev = $next = null;

    $aKeys = array_keys($haystack);
    $k = array_search($needle,$aKeys);
    if ($k !== false) {
        if ($k > 0)
            $prev = array($aKeys[$k-1] => $haystack[$aKeys[$k-1]]);
        if ($k < count($aKeys)-1)
            $next = array($aKeys[$k+1] => $haystack[$aKeys[$k+1]]);
    }
    return array($prev,$next);
}

print_r(getPrevNext($array,$srch));

echo "</pre><hr>";

е то въпроса ми е как да взема id-тата с една заявка 🙂 Начина na @bubatalazi работи но незнам дали ще бъде по-бърз при много записи.
 
Re: mysql заявка

нали си на текуща снимка?

има си id за да я извадиш

с тази функция взимаш всички id-та на снимки, и ти показва предишно и следващо id на текущото
 
Re: mysql заявка

доколкото те разбирам искаш с една заявка да взема всички ид-та на снимките - в моя случай масива ще стане с около 500,000 елемента🙂

$array = array(1,2,3...500000);

ако типа int е 4 байта това са близо 2МБ масив - няма да ми стигне рама маргарин 🙂
 
Последно редактирано:
Re: mysql заявка

имаш потребител с галерия

едвали той ще има 500К снимки в една галерия

както и да е...
 
Re: mysql заявка

Ами основния потребител който пълни сайта е с един акаунт и вече има около 420К снимки. Но ти си прав - ако ги пръсна тези снимки равномерно на 50 измислени потребителя ще стане работата... Незнам само дали ще има ефект спрямо бързината на зареждане...
 
Re: mysql заявка

е то въпроса ми е как да взема id-тата с една заявка 🙂 Начина na @bubatalazi работи но незнам дали ще бъде по-бърз при много записи.

Ако наистина имаш dataset с 50к записа, пусни един EXPLAIN и дай резултата - ще покаже ако има проблем. Иначе мисля, че един индекс (user_id, pic_id) ще ти е достатъчен.
 
Re: mysql заявка

http://www.w3schools.com/sql/sql_between.asp

Иначе, варианта на krapo е по-добър ако знаеш точните краен брой айдита.

Другия вариант е с кеш в същата или отделна таблица с предното и следващото айди.

Ако бройката редове в резултата е по малка от 3 значи нещо не е в ред и пускаме опресняване на кеша само за потребителя,
не е нужно да рефрешваме цялата/всичките кеш таблица/записи... 😉

Като подобни манипулации биха били много рядко нещо...

1 бърза заявка + 1 тежка но рядка опресняваща само при нужда.

Разбира се всичко зависи от конкретната система и нужди за които до момента няма много информация. ;D
 

Back
Горе