Код, раскидывающий результаты одной таблицы в другие по признаку

  • Автор темы BeatBox
  • Дата начала

BeatBox

Guest
выводит всесто последних добавлений (их всего4) - 4 раза одно и то же + не просчитывает почему-то среднее по голосам :(

-~{}~ 07.03.05 03:16:

уже ближе!
вот такой вариант выводит правда только одно добавление, но выводит корректно, и просчитывает ему среднее по голосам:
PHP:
$resultc = $db->sql_query("SELECT a.pid as pid, a.title as title, AVG(b.vote_mark) as vote_mark FROM ".$prefix."_pages a, ".$prefix."_vote b WHERE a.game_id=b.vote_id GROUP BY b.vote_id order by pid limit 0, 50");
while ($row = $db->sql_fetchrow($resultc)) {
$vm = $row['vote_mark'];
$pid = $row['pid'];
 

SelenIT

IT-лунатик :)
А голоса в таблице голосований есть по всем четырем добавлениям или только по тому, которое выводится?
 

BeatBox

Guest
Ещё ближе1 убрал из кода убрал из кода "WHERE a.game_id=b.vote_id" теперь показываються все добавления, по одному разу (Как и надо) то оценка подсчитана для всех одна :(

-~{}~ 07.03.05 03:28:

SelenIT
голоса есть по всем. Но вообще-то нужно чтобы скрипт не сбивался если и нету голосов.
 

SelenIT

IT-лунатик :)
Это не ближе - условие при where показывает, что данное голосование относится к данной статье.

А группировать, конечно, изначально нужно было по id-у. Извиняюсь, что показал ошибочный пример.

А чтоб скрипт не сбивался, попробуй другую разновидность объединения:

PHP:
$resultc = $db->sql_query("SELECT a.pid as pid, a.title as title, AVG(b.vote_mark) as vote_mark FROM ".$prefix."_pages a LEFT JOIN ".$prefix."_vote b ON a.game_id=b.vote_id GROUP BY a.game_id order by pid limit 0, 50");
 

BeatBox

Guest
вот вообще весь код, может я там что не так делаю:
PHP:
код убран автором
извините за обьёмы
 

SelenIT

IT-лунатик :)
Это точно полный код? Непонятно, как он вообще может вывести больше одной строки. Фигурные скобки стоят именно так?

И еще меня покоробил перевод даты в unix_timestamp, а из него - в читабельную строку. Зачем, когда в самой MySQL есть DATE_FORMAT?
 

BeatBox

Guest
SelenIT
ну это не совсем полный код. Вот ниже выкладываю абсолютно полный код (просто нехотел нагружать топик большими кодами).:

PHP:
код убран автором
-~{}~ 07.03.05 04:06:

сам код немного сыроват, не добавил в него 4sort но это неважно - точно такойже модуль уже есть рабочий (у меня) но там нету вывода результатов голосования..
 

SelenIT

IT-лунатик :)
нехотел нагружать топик большими кодами
Правильно делал. Меня интересовала одна-единственная скобка :)

Мда, "немного сыроват" - это мягко сказано :) Зачем было городить столько разнородных задач в одну функцию-монстра?

Немного его "причесал" - все равно криво, но уже хоть более-менее понятно, что откуда берется и куда девается)
PHP:
<?
function list_pages(/* параметры, определяющие выборку, нужно передавать сюда */) {
  global $prefix, $db /*нужно внимательно просмотреть список глобальных переменных:
                        очень много лишнего, многого не хватает */;
    echo tableheader(/* набор параметров */); /* этот дикий блок if-elseif-else
                                                который здесь все равно не работает,
                                                нужно вынести в другую ф-цию */
    ?>
<TABLE id=list_table cellSpacing=0 cellPadding=1 width="100%" border=0>
  <TBODY>
<?
    $resultc = $db->sql_query("SELECT a.pid AS pid, DATE_FORMAT('%d.%m.%Y',a.date) AS formatted, 
                                      a.title AS title, AVG(b.vote_mark) AS vote_mark 
                               FROM ".$prefix."_pages a 
                               LEFT JOIN ".$prefix."_vote b ON a.game_id=b.vote_id 
                               GROUP BY a.game_id");
    while ($row = $db->sql_fetchrow($resultc)) {
?>
    <TR>
      <TD class=<?=$table_classtd?> id=brb vAlign=top noWrap><?=$row["formatted"]?></TD>
      <TD class=<?=$table_classtd?> vAlign=top>
        <A class=sb href="page.php?name=content&pa=showpage&pid<?=$row["pid"]?>"><?=$row["title"]?></A>
        <BR>
        <?=$style?>
      </TD>
      <TD class=$table_classtd><?=$row["vm"]?></TD>
    </TR>
<?
    }
?>
  </TBODY>
</TABLE>
<?
}

include("header.php");
list_pages(/*здесь нужные параметры выборки*/);
include("footer.php");

?>
Ох, не повезло тебе с образцами кода. Прав был uchenik - легче аккуратно написать с нуля...
 

BeatBox

Guest
так получилось ;)
блин но все-таки незнаю что и делать с этим выводом голосов.. :(
сейчас вариант:
PHP:
$resultfx = $db->sql_query("SELECT a.pid as pid, UNIX_TIMESTAMP(a.date) as formatted, a.title as title, AVG(b.vote_mark) as vote_mark FROM ".$prefix."_pages a, ".$prefix."_vote b WHERE a.game_id=b.vote_id GROUP BY a.pid");
while ($row9 = $db->sql_fetchrow($resultfx)) {
$vm = $row9['vote_mark'];
$pid = $row9['pid'];
$title = $row9['title'];
$gamedate = date("d.m.Y", $row9["formatted"]);
-~{}~ 07.03.05 04:34:

выводит только одно добавление :(
 

SelenIT

IT-лунатик :)
а скобка после этих манипуляций и перед сборкой переменной $games случайно снова не закрыта?
 

SelenIT

IT-лунатик :)
гм... а pid у этих четырех добавлений точно не совпадает?
что вообще у этих добавлений уникальное?
подозреваю, что все-таки game_id...
 

BeatBox

Guest
нет, гейм_айди повторяеться только в site_vote, потому как когда юзер голосует, записываеться примерно так:

game | id698 | 80 | BeatBox

первое - говорит что проголосовали за игру,
второе - это айди игры за которую голосовали
третье - оценка
четвертое - кто голосовал.

так что если 3 чел. проголосвали за одну игру то будет типа:
game | id698 | 80 | BeatBox
game | id698 | 90 | SelenIT
game | id698 | 100 | uchenik
а в таблице из которой беруть добавления - ничего общего, разве что даты могут совпадать.
 

SelenIT

IT-лунатик :)
Не могу больше строить предположений, не видя данных из таблицы ххх_pages (только не надо их сюда постить :) )

Попробуй еще немного поэкспериментировать - попробуй вариант с LEFT JOIN-ом, к примеру. А лучше сделай перерыв и потом поищи ошибку свежим взглядом.
 

BeatBox

Guest
МДА!!!!! незнаю...я сейчас чувствую себя полным идиотом - знаете как все заработало? НЕТ СЛОВ!
ПРОСТО ДОБАВИЛ ТОЧКУ ПЕРЕД знаком равно вот:

PHP:
$games .= "<TR>
    <TD class=$table_classtd id=brb vAlign=top noWrap>$gamedate</TD>
    <TD class=$table_classtd vAlign=top><A class=sb
                  href=\"page.php?name=content&amp;pa=showpage&amp;pid=$pid\">$title</A><BR>
      $style</TD>
    <TD class=$table_classtd>$vm</TD>
  </TR>";
сейчас проверю все ли так хорошо как мне кажеться.

Только ещё пролемка - выводит числа с 3мя знаками после запятой, а нужно вообще только целы чтобы показывало. Можно так?

-~{}~ 07.03.05 05:52:

последняя недоработка - если у игры нет голосов, то её не показывают.
хочу это исправит так:
после сеекта если ноль эмоций от бд то селект заменяетьсяя на такой же, кроме - не обращаеться в бд за голосами.

-~{}~ 07.03.05 06:02:

с округлением разобрался. Осталось только научить выводить добавления, если нету у них голосов.
 

SelenIT

IT-лунатик :)
C точкой все правильно - она означает, что новая строка допишется к переменной, а не перепишет ее. Это базовый синтаксис php. Вот только куда она пропадала, ведь в обоих примерах она была на месте...

Чтобы $vm была целым числом - варианты:

$vm = (int)$row9['vote_mark'];
$vm = [m]intval[/m]($row9['vote_mark']);
$vm = [m]round[/m]($row9['vote_mark']);
(есть и другие, но, думаю, для начала достаточный выбор, плюсы и минусы предлагаю определить экспериментально).

Последняя недоработка автоматически устраняется заменой простого объединения на LEFT JOIN. Пример уже дан.
 

BeatBox

Guest
SelenIT
во--первых ОГРОМНОЕ спасибо за всю помощь мне! ОГРОМНЕ!

и вот я сделал с лефт джойн. посмотрите пожалуйста, правильно?
(работает нормально, но вдруг код непраильно составил)
PHP:
$resultre = $db->sql_query("SELECT a.pid as pid, UNIX_TIMESTAMP(a.date) as formatted, a.title as title, AVG(b.vote_mark) as vote_mark FROM ".$prefix."_pages as a LEFT JOIN ".$prefix."_vote as b on (a.game_id=b.vote_id) GROUP BY a.pid ORDER BY $sortby $stype limit 0, 50");
-~{}~ 07.03.05 06:30:

SelenIT
ещё можно вопросик? можно ли в этот запрос вложить тоже вывод результатов, но там ещё будет дополнительное условие - user_voted в таблице site_vote должно равняться определенному нику (точнее нескольким никам, но это неважно)
 

SelenIT

IT-лунатик :)
BeatBox
во-первых, пожалуйста :)

в запросе беглым взглядом серьезных ошибок не вижу, вот только
1) Надежнее группировать по тому же столбцу, по которому присоединяются данные голосований, т.е. по a.game_id.
2) Дался тебе этот UNIX_TIMESTAMP! Зачем делать двойное неудобное преобразование (в базе и потом в скрипте), если можно получить из базы готовую красивую дату с помощью специальной функции DATE_FORMAT. Пример запроса с ней тоже уже есть в топике.

А так - молодец. Видишь, все-таки удалось решить твою задачу, не прибегая к извращениям вроде "разброса" результатов по таблицам. А заодно сколько нового узнал...

По дополнительному вопросу: можно - добавится условие в where. Но нужно ли? Ох, боюсь, ты опять пытаешься что-то усложнить ;)
 

BeatBox

Guest
Спасибо ещй раз. Да действительно узнал много нового ;) Ладно, буду спать ложиться.
Спокойной ночи :)

-~{}~ 07.03.05 07:23:

SelenIT
если всё-таки можно, то обьясните поподробней как можно ещё вывест в этот же запрос среднее кол-во результатов, с этим же vote_id но + где user_voted = '$staff' (эта переменная береться их файла конфига).
этот второй результат должен отображаться не вместо предыдущего а рядом.
Буду очень благодарен! дело в том что на самой страничке голосования и результатов я вывожу результаты среди юзеров и админов отдельно, и если тут не выведу - то скажу что это глюк (юзеры ;) ) ну и вообще глупо смотриться. Помогите пожалуйста.
Если ставить Where то это же уже будет второй WHERE. И впринципе тогда WHERE будет действовать на весь запрос (насколько я понимаю).
С Уважением!
 

SiMM

Новичок
> нехотел нагружать топик большими кодами
На будущее - для большого кода существует http://phpclub.ru/paste/ - просто это в правилах почему-то до сих пор не отражено
 
Сверху