1

次のクエリは、奇妙な結果を返します。

SELECT
    `Statistics`.`StatisticID`,
    COUNT(`Votes`.`StatisticID`) AS `Score`,
    COUNT(`Views`.`StatisticID`) AS `Views`,
    COUNT(`Comments`.`StatisticID`) AS `Comments`
FROM `Statistics`
LEFT JOIN `Votes` ON `Votes`.`StatisticID` = `Statistics`.`StatisticID`
LEFT JOIN `Views` ON `Views`.`StatisticID` = `Statistics`.`StatisticID`
LEFT JOIN `Comments` ON `Comments`.`StatisticID` = `Statistics`.`StatisticID`
GROUP BY `Statistics`.`StatisticID`
LIMIT 0, 10

次のようなテーブル構造でこれをクエリしています。

(に関連するデータのみStatistics.StatisticID = 8

投票

StatisticID
    8

ビュー

StatisticID
    8
    8

コメントコメント

StatisticID
    8
    8
    8
    8
    8

このクエリを実行すると、次の結果セットが得られます。

StatisticID    Score    Views   Comments
     8           5        5        5

私は5がどこから来ているのか(コメントの数)を知っています。これは、コメントステートメントを削除すると機能します。これは私の手の届かないところにあるので、誰かがこれをデバッグできますか(私はSQLに比較的慣れていません)。

ありがとう、ロス

4

2 に答える 2

4

このように結合すると、他のテーブルで数学行を見つけた回数だけデータが複製されます。各テーブルに対応する行が 1 つしかない場合は、これで問題ありません。

グループ化せずにこのクエリを実行すると、すべてのカウントで同じ結果が得られる理由がわかります。ただし、すべてのフィールド (1*2*5) のカウントとして 10 を取得すると推測していました。これを解決するには、カウントごとにサブセレクトを呼び出す必要があります。

選択する
    s.`StatisticID`,
    (SELECT COUNT(*) FROM Votes WHERE Votes.StatisticID = s.StatisticID) AS スコア、
    (SELECT COUNT(*) FROM Views WHERE Views.StatisticID = s.StatisticID) AS ビュー、
    (SELECT COUNT(*) FROM Comments WHERE Comments.StatisticID = s.StatisticID) AS コメント、
FROM `Statistics` s
リミット 0、10

外側の結果が大きい場合、これには特定のパフォーマンスの問題があります。テーブルの 1 つを結合して少し最適化することもできますが、クエリパーサーが、グループ化された項目ごとに 1 回だけ実行できるほどスマートかどうかはわかりません。うまくいけば、そうなるでしょう。そうしないと、別のクエリに分割できます。

于 2008-11-20T22:34:11.880 に答える
2

投票/ビュー/コメントに id フィールドまたは同様のものがあると仮定します:

SELECT
    `Statistics`.`StatisticID`,
    COUNT(DISTINCT `Votes`.`VoteID`) AS `Score`,
    COUNT(DISTINCT `Views`.`ViewID`) AS `Views`,
    COUNT(DISTINCT `Comments`.`CommentID`) AS `Comments`
FROM `Statistics`
LEFT JOIN `Votes` ON `Votes`.`StatisticID` = `Statistics`.`StatisticID`
LEFT JOIN `Views` ON `Views`.`StatisticID` = `Statistics`.`StatisticID`
LEFT JOIN `Comments` ON `Comments`.`StatisticID` = `Statistics`.`StatisticID`
GROUP BY `Statistics`.`StatisticID`
LIMIT 0, 10

テストしていませんが、動作するはずです。(statisticID は特定のグループ内で常に同じであるため、別のフィールドを使用する必要があります...)

于 2008-11-20T23:40:16.943 に答える