1

次の SQL クエリがあります。

SELECT tblBooks.bookID,
    tblBooks.title,
    tblBooks.author,
    tblBooks.coverImage,
    ROUND(ROUND(tblReviews.rating * 2) / 2, 1) AS rating
FROM tblBooks
    LEFT JOIN tblReviews
        ON tblBooks.bookID = tblReviews.bookID
        LEFT JOIN tblMembers
            ON tblReviews.userID = tblMembers.userID
WHERE tblReviews.bookID IS NOT NULL
ORDER BY rating DESC
LIMIT 0, 40

データベースにクエリを実行して平均評価を返したいので、本が 6 回レビューされている場合、6 人のユーザーからの各評価を合計して平均を計算します。現在、最新の評価のみが返されています。この行を次のように変更すると:

ROUND(ROUND(AVG(tblReviews.rating) * 2) / 2, 1) AS rating

合計で 1 つの結果しか返されないため、明らかに何か問題がありますが、何が原因かわかりません。

誰かがこれに光を当てることができれば、それは私の結合と関係があると思います.

4

5 に答える 5

3

group by次のように使用する必要があります。

SELECT tblBooks.bookID, tblBooks.title, tblBooks.author, tblBooks.coverImage,
       AVG(tblReviews.rating) as avgRating
FROM tblBooks
     LEFT JOIN tblReviews
     ON tblBooks.bookID = tblReviews.bookID
WHERE tblReviews.bookID IS NOT NULL
group by tblBooks.bookID, tblBooks.title, tblBooks.author, tblBooks.coverImage
ORDER BY avgrating DESC

あなたのクエリは、Members テーブルの情報を使用していないように見えるので、削除しました。を使用しているため、それに基づいてフィルタリングすることさえありませんleft join

于 2013-04-18T17:38:34.680 に答える
1

AVG代わりに使用しないのはなぜですか?

SELECT tblBooks.bookID,
    tblBooks.title,
    tblBooks.author,
    tblBooks.coverImage,
    AVG(tblReviews.rating) AS rating
FROM tblBooks
    LEFT JOIN tblReviews
        ON tblBooks.bookID = tblReviews.bookID
        LEFT JOIN tblMembers
            ON tblReviews.userID = tblMembers.userID
WHERE tblReviews.bookID IS NOT NULL
Group By tblBooks.bookID, tblBooks.title, tblBooks.author, tblBooks.coverImage
ORDER BY rating DESC
LIMIT 0, 40

ご参考までに

MYSQL では、すべての列でグループ化する必要はありませんが、他の RDMS を使用するときに必要になるため、良い方法です。

于 2013-04-18T17:39:55.403 に答える
1

どちらも必要ありませんWHERE。あなたは本質的にINNER結合を行っています:

SELECT t.bookID,
       t.title,
       t.author,
       t.coverImage,
       AVG(r.rating) AS rating
FROM tblBooks AS t
    JOIN tblReviews AS r
        ON b.bookID = r.bookID
GROUP BY t.bookID
--     , t.title, t.author, t.coverImage 
ORDER BY rating DESC
LIMIT 40 ;

注:が の主キーである (または一意の制約がある)GROUP BY t.bookID場合にのみ、(他の列を使用せずに) のみを使用すると正しい結果が得られます。他のすべての DBMS はこれを許可しません (Postgres を除きますが、その製品は機能を正しく実装しており、他の列がグループ化列に依存しているかどうかをチェックします)。MySQL はまったくチェックしないため、多くの場合、誤った結果が返される可能性があります。bookIDtblBooks

sql_mode上記がエラーなしで実行されるかどうかは、設定​​にも依存します。


または、最初にグループ化してから参加することもできます。これは有効な SQL であり、エラーが発生する可能性はありません。

SELECT t.bookID,
       t.title,
       t.author,
       t.coverImage,
       g.rating
FROM tblBooks AS t
    JOIN 
        ( SELECT r.bookID,
                 AVG(r.rating) AS rating
          FROM tblReviews AS r
          GROUP BY r.bookID
        ) AS g
        ON b.bookID = r.bookID
ORDER BY rating DESC
LIMIT 40 ;
于 2013-04-18T17:49:57.533 に答える
0

あなたに欠けているのは

 GROUP BY tblBooks.bookID, tblBooks.title, tblBooks.author, etc...

AVG はデータを合計する集計関数です。GROUP BY を使用して集計のグループを作成します。

于 2013-04-18T17:35:49.187 に答える
0

これを試して:

...
WHERE tblReviews.bookID IS NOT NULL
GROUP BY tblBooks.bookID
ORDER BY rating DESC
LIMIT 0, 40

乾杯。

于 2013-04-18T17:36:16.573 に答える