0

最高評価から最低評価まで、評価順に並べられたテーブルからレコードを返すこの PHP/MYSQL コードがあります。

<table width="95%">
    <tr>
    <?php
        if (isset($_GET['p'])) {
            $current_page = $_GET['p'];
        } else {
            $current_page = 1;
        }
        $cur_category = $_GET['category'];
        $jokes_per_page = 40;
        $offset = ($current_page - 1) * $jokes_per_page;

        $result = mysql_query("
        select jokedata.id as joke_id, jokedata.datesubmitted as datesubmitted,
        jokedata.joketitle as joke_title, sum(ratings.rating)/count(ratings.rating) as average
        from jokedata inner join ratings
        on ratings.content_type = 'joke' and ratings.relative_id = jokedata.id
        WHERE jokecategory = '$cur_category'
        group by jokedata.id
        order by average desc
        limit $offset, $jokes_per_page
        ");

        $cell = 1;
        while ($row = mysql_fetch_array($result)) {
            if ($cell == 5) {
                echo "</tr><tr class=\"rowpadding\"><td></td></tr><tr>";
                $cell = 1;
            }
            $joke_id = $row['joke_id'];
            $joke_title = $row['joke_title'];
            $joke_average = round($row['average'], 2);

            echo "<td><strong><a class=\"joke_a\" href=\"viewjoke.php?id=$joke_id\">$joke_title</a></strong> -average rating $joke_average.</td>";
            $cell++;
        }
    ?>
    </tr>
    <tr class="rowpadding"><td></td></tr>
</table>

これは完璧に機能しますが、問題が 1 つあります。項目に少なくとも 1 つの評価がない場合、クエリによってまったく選択されません!

どうすればこれを修正できますか? ありがとう。

4

4 に答える 4

1

これを試して:

SELECT  jokedata.id as joke_id,
        jokedata.datesubmitted as datesubmitted,
        jokedata.joketitle as joke_title,
        COALESCE(
        (
        SELECT  AVG(rating)
        FROM    ratings
        WHERE   ratings.relative_id = jokedata.id
                AND ratings.content_type = 'joke'
        ), 0) AS average
FROM    jokedata
ORDER BY
        average DESC
LIMIE   $offset, $jokes_per_page
于 2009-04-09T08:45:01.980 に答える
1

内部結合ではなく左結合を使用して、ratings.ratings が null の場合を処理する必要があります。

$result = mysql_query("
            SELECT jokedata.id AS joke_id, 
            jokedata.datesubmitted AS datesubmitted,
            jokedata.joketitle AS joke_title, 
            -- average is 0 if count or sum is null
            IFNULL(SUM(ratings.rating)/COUNT(ratings.rating), 0) AS average
            FROM jokedata 
            -- return all rows from left table (jokedata), and all nulls for ratings
            -- data when there is no matching row in the right table (ratings)
            LEFT JOIN ratings ON ratings.content_type = 'joke' AND jokedata.id = ratings.relative_id 
            WHERE jokecategory = '$cur_category'
            GROUP BY jokedata.id
            ORDER BY average desc
            LIMIT $offset, $jokes_per_page
            ");

左結合は、jokedata からすべての結果を返し、結合条件が満たされていない各行の評価についてはすべて null を返します。

于 2009-03-28T11:20:56.250 に答える
0

平均を使うのは少し不公平に思えます。ジョーク A の評価が 5 で、ジョーク B の評価が 4 である場合、ジョーク A はジョーク B より上位にランク付けされます。

重みを評価に関連付けてから、重みでランク付けすることをお勧めします。たとえば、1 から 5 までのスケールでは、1 は -2、2 は -.5、3 は 0、4 は +.5、5 は +2 になります。したがって、これにより、「4」の評価が 5 のジョークは、「5」の評価が 1 のジョークよりも高くランク付けされます。

-2 から +2 のスケールには微調整が必​​要かもしれませんが、私の言いたいことを理解していただければ幸いです。

于 2009-04-09T03:57:45.570 に答える