За последние 24 часа нас посетили 22583 программиста и 1139 роботов. Сейчас ищут 604 программиста ...

рейтинг пользователя общий

Тема в разделе "PHP для новичков", создана пользователем zx16, 23 июн 2014.

  1. zx16

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

    С нами с:
    23 июн 2014
    Сообщения:
    4
    Симпатии:
    0
    Ребята, как выполнить определение места пользователя. к примеру есть таблица оценок :
    [​IMG]
    uid - это иды пользователей которых оценивали.
    ball - это оценка.

    еще есть таблица пользователей:
    [​IMG]

    id - id пользователя
    tip - это тип пользователя, оценивается только тип 4, а два не трогаем..

    Рейтинг для одного пользователя реализовал таким способом, но это только его индивидуальный рейтин = сумма оценок / сумма оценивших .

    Код (Text):
    1. $o=(sprintf("%01.1f", $db->one_data('SELECT AVG(ball) FROM '.DB_PREFIX."ocenka WHERE uid='$user[id]'")));

    количество нужных нам пользователей, среди которых отбираем лучших:
    Код (Text):
    1. $k=$db->one_data('SELECT COUNT(*) FROM '.DB_PREFIX."users WHERE id AND tip=4");
    как это все объединить, чтобы получить к примеру UserGOOD (1-й из 50)
    . помогите, весь день в css разбирался, на php голова вовсе не варит уже) да и слаб я в этом очень.. ЗАРАНЕЕ БЛАГОДАРЕН!
     
  2. Bio

    Bio Новичок

    С нами с:
    17 июн 2014
    Сообщения:
    18
    Симпатии:
    0
    По приведённым скриншотам кто на первом месте? Определять по: "хорошо доставил", "отлично"? Или по каким критериям?
    Как я вижу у zx16 descr=Нормально
     
  3. zx16

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

    С нами с:
    23 июн 2014
    Сообщения:
    4
    Симпатии:
    0
    Василий и zx16 к примеру вот их два человека, нам нужно вывести строку в личном кабинете к примеру, у zx16 - 1й из 2 . понимаете? блин, картинки обрезаны. нет полей еще дополнительных.. 3ka.info/1.png и 3ka.info/2.png . там картины полнее. у каждого юзера есть строка ball в табл оценка, это баллы от других пользователей . и исходя из них нужно определить какую строку юзер занимает из всего количества юзеров
     
  4. Bio

    Bio Новичок

    С нами с:
    17 июн 2014
    Сообщения:
    18
    Симпатии:
    0
    Код (Text):
    1.  
    2. <?php
    3. $user="Bio"; // Ник пользователя, который будет проверяться.
    4. $link=mysqli_connect("***","***","***","top_users")or die(mysqli_error($link));
    5. $sql="SELECT id,login FROM users WHERE tip=4";
    6. $result=mysqli_query($link,$sql)or die(mysqli_error($link));
    7. $arrUsers=array();
    8. $i=0;
    9. $str="";
    10. while($row=mysqli_fetch_assoc($result)){
    11.     $arrUsers[]=$row;
    12.     $str.="{$arrUsers[$i]['id']},";
    13.     $i++;
    14. }
    15. $str=substr($str,0,-1);
    16. $sql="SELECT ball,uid FROM ocenka WHERE uid IN($str)";
    17. $result=mysqli_query($link,$sql)or die(mysqli_error($link));
    18. $arrOcenka=array();
    19. while($row=mysqli_fetch_assoc($result)){
    20.     $arrOcenka[]=$row;
    21. }
    22. rsort($arrOcenka);
    23. foreach($arrUsers as $v){
    24.     if($v["login"]==$user){
    25.         $id=$v["id"];
    26.     }
    27. }
    28. $int=count($arrOcenka);
    29. foreach($arrOcenka as $k=>$v){
    30.     if($v["uid"]==$id)
    31.         echo "$user ".($k+1)."/ $int";
    32. }
    33. ?>
     
  5. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.554
    Симпатии:
    1.754
    Ну так отсортировать по количеству баллов (по убыванию), и проверять позицию в массиве. Я так сделал. Только для рейтинга отдельную табличку поставил, поскольку у меня связей больше в проекте. А чтоб лишний раз не лазить в БД, сделал кеширование этой таблицы с рейтингами
     
  6. artoodetoo

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

    С нами с:
    11 июн 2010
    Сообщения:
    11.072
    Симпатии:
    1.237
    Адрес:
    там-сям
    @zx16:
    Лучший способ рассказать что-то о базе и напроситься на хорошие запросы — подготовить пример на sqlfiddle.com
    А скришноты pma это худший способ )))

    Насколько я понял твою картину, очень геморно сходу вычислить на каком месте человек внутри своей группы. Рекомендую завести специальную таблицу для ранжирования пользователей и периодически (по крону или вручную) актуализировать ее.

    Очевидно сортируем пользователей по убыванию avg(ball).
    Код (Text):
    1. SELECT o.uid, AVG(o.ball) AS avg_rating
    2. FROM ocenka AS o INNER JOIN users AS u ON o.uid=u.id AND u.tip=4
    3. GROUP BY 1
    4. ORDER BY 2 DESC
    Трюк с нумерацией строк в выборке с сортировкой можно подсмотреть здесь: http://stackoverflow.com/a/3614741/272885
    Код (Text):
    1. SELECT t.uid,  t.avg_rating,  @rownum := @rownum + 1 AS position
    2. FROM
    3.   (
    4.     SELECT o.uid, AVG(o.ball) AS avg_rating
    5.     FROM ocenka AS o INNER JOIN users AS u ON o.uid=u.id AND u.tip=4
    6.     GROUP BY 1
    7.   ) AS t
    8.   JOIN (SELECT @rownum := 0) AS r
    9. ORDER BY t.avg_rating
    Остается сохранить эти данные чтобы не вычислять постоянно.

    Код (Text):
    1. TRUNCATE rank;
    2.  
    3. INSERT INTO rank(uid, avg_rating, position)
    4. SELECT предыдущий запрос )))
    Как часто сохранять — дело твоё. Главное что не при каждом просмотре пользовательского профиля.

    Теперь у тебя под рукой будет источник откуда ты можешь достать балл и место любого пользователя (из группы 4, мы только ее сохраняли).
    Код (Text):
    1. SELECT avg_rating, position FROM rank WHERE uid=:id
     
  7. zx16

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

    С нами с:
    23 июн 2014
    Сообщения:
    4
    Симпатии:
    0
    Вижу вы очень хорошо разбираетесь в этом! для меня это сложновато пока(((( чтоб собрать это все в кучу..
     
  8. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.554
    Симпатии:
    1.754
    Красиво :)
     
  9. zzx16

    zzx16 Новичок

    С нами с:
    7 июл 2014
    Сообщения:
    4
    Симпатии:
    0
    не записывает в базу данных((
    вот такой следуя вашей инструкции:

    Код (Text):
    1.  
    2. $sql = '
    3. INSERT INTO top(uid, avg_rating, sumball,position)
    4. SELECT t.uid,  t.avg_rating, t.sumball,  @rownum := @rownum + 1 AS position
    5. FROM
    6.   (
    7.     SELECT o.uid, AVG(o.ball) AS avg_rating,  SUM(o.ball) AS sumball
    8.     FROM free_courier_ocenka AS o INNER JOIN free_courier_users AS u ON o.uid=u.id AND u.tip=1
    9.     GROUP BY 1
    10.   ) AS t
    11.   JOIN (SELECT @rownum := 0) AS r
    12. ORDER BY t.sumball
    13.  
    14. ';

    я чуть переделал, так как точнее будет выводить рейтинг пользователей по сумме оценок, а не по средней. чуть дописал в код но в базу не пишет значения. ошибок нет после sql запроса . просто база пуста. тип (u.tip=1) изменил в базе, на это не обращайте внимания, и все базы прописал правильно.
     
  10. artoodetoo

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

    С нами с:
    11 июн 2010
    Сообщения:
    11.072
    Симпатии:
    1.237
    Адрес:
    там-сям
    если запись не создается, значит ошибка есть. отлаживай.
    http://phpfaq.ru/debug

    Добавлено спустя 2 минуты 27 секунд:
    p.s. подготовь пример с данными sqlfiddle.com , будет больше толку, чем от "ничего не получается помогите".
    помогают тому, кто сам себе помогает.
     
  11. zzx16

    zzx16 Новичок

    С нами с:
    7 июл 2014
    Сообщения:
    4
    Симпатии:
    0

    ну так нету

    Код (Text):
    1. $sql = '
    2. INSERT INTO top(uid, avg_rating, sumball,position)
    3. SELECT t.uid,  t.avg_rating, t.sumball,  @rownum := @rownum + 1 AS position
    4. FROM
    5.   (
    6.     SELECT o.uid, AVG(o.ball) AS avg_rating,  SUM(o.ball) AS sumball
    7.     FROM free_courier_ocenka AS o INNER JOIN free_courier_users AS u ON o.uid=u.id AND u.tip=1
    8.     GROUP BY 1
    9.   ) AS t
    10.   JOIN (SELECT @rownum := 0) AS r
    11. ORDER BY t.sumball
    12.  
    13. ';
    14.  
    15. if(!mysql_query($sql))
    16. {echo '<center><p><b>Ошибка при добавлении данных!</b></p></center>';}
    17. else
    18. {echo '<center><p><b>Нормик!</b></p></center>';}
    выводит НОРМИК!

    p.s. не пользовался sqlfiddle.com , изучу как он работает. Пока времени нету(
     
  12. artoodetoo

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

    С нами с:
    11 июн 2010
    Сообщения:
    11.072
    Симпатии:
    1.237
    Адрес:
    там-сям
    а у нас значит есть время. ок. эксплуатируй нас полностью!

    сделай еще вывод mysql_affected_rows() сразу после удачной вставки. подозреваю что тупо 0 строк было вставлено, то есть SELECT выдал пустой набор строк для вставки.
     
  13. zzx16

    zzx16 Новичок

    С нами с:
    7 июл 2014
    Сообщения:
    4
    Симпатии:
    0
    вывод 0 .
     
  14. artoodetoo

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

    С нами с:
    11 июн 2010
    Сообщения:
    11.072
    Симпатии:
    1.237
    Адрес:
    там-сям
    запускай phpmyadmin, копируй туда SELECT и разбирайся почему он выдал 0 строк.

    скорее всего оценок нет. наверное надо изменить запрос так, чтобы он выдавал дефолтовые значения даже при отсутствии оценок — с помощью LEFT JOIN и ifnull()

    завидую я тебе, столько открытий чудных тебе предстоит ;)
     
  15. zzx16

    zzx16 Новичок

    С нами с:
    7 июл 2014
    Сообщения:
    4
    Симпатии:
    0
    ну а sql запрос на phpmyadmin не выводит никаких ошибок. запрос выполняется и все. все зелененькое и красивое. короче чутка переделал и заработало:

    старый код:
    Код (Text):
    1. INSERT INTO top(uid, avg_rating, sumball,position)
    2. SELECT t.uid,  t.avg_rating, t.sumball,  @rownum := @rownum + 1 AS position
    3. FROM
    4.   (
    5.     SELECT o.uid, AVG(o.ball) AS avg_rating,  SUM(o.ball) AS sumball
    6.     FROM free_courier_ocenka AS o INNER JOIN free_courier_users AS u ON o.uid=u.id AND u.tip=1
    7.     GROUP BY 1
    8.   ) AS t
    9.   JOIN (SELECT @rownum := 0) AS r
    10. ORDER BY t.sumball
    новый код:
    Код (Text):
    1. INSERT INTO top(uid, avg_rating, sumball,position)
    2. SELECT t.uid,  t.avg_rating, t.sumball,  @rownum := @rownum + 1 AS position
    3. FROM
    4.   (
    5.     SELECT o.uid AS uid, AVG(o.ball) AS avg_rating,SUM(o.ball) AS sumball,COUNT(o.ball) AS position
    6.     FROM free_courier_ocenka AS o INNER JOIN free_courier_users AS u ON o.uid=u.id AND u.tipt=1
    7.     GROUP BY 1
    8.   ) AS t
    9.   JOIN (SELECT @rownum := 0) AS r
    10. ORDER BY 3 DESC
    теперь у нас есть таблица, в которой мы имеем id пользователя (uid) , среднюю его оценку (avg_rating), сумму всех его оценок (sumball) и самое главное - его позицию среди всех оцениваемых пользователей (position) . Огромное спасибо artoodetoo , который возился со мной как мамочка!!
     
  16. artoodetoo

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

    С нами с:
    11 июн 2010
    Сообщения:
    11.072
    Симпатии:
    1.237
    Адрес:
    там-сям