2009-09-22 5 views
1
SELECT game_ratingstblx245v.game_id,avg(game_ratingstblx245v.rating) 
     as avg_rating, 
     count(DISTINCT game_ratingstblx245v.userid) 
      as count, 
     game_data.name, 
     game_data.id , 
     avg(game_ratings.critic_rating),count(DISTINCT game_ratings.critic) 
     as cr_count 
FROM game_data 
LEFT JOIN game_ratingstblx245v ON game_ratingstblx245v.game_id = game_data.id 
LEFT JOIN game_ratings   ON game_ratings.game_id = game_data.id 
WHERE game_data.release_date < NOW() 
GROUP BY game_ratingstblx245v.game_id 
ORDER BY game_data.release_date DESC, 
     game_data.name 


J'utilise currenty cette requête pour extraire des valeurs de 3 tables
game_data - id (clé étrangère), nom, jeux release_date de \ informations
game_ratings - game_id (clé étrangère), critique, note \ critique note
game_ratingstblx245v - game_id (clé étrangère), note, userid \ user ratingAide dans une requête de jointure


ce que je veux faire avec cette requête est de sélectionner tous les id de la commande table game_data par release_date descendant, puis vérifiez la Note moyenne de game_ratings et game_rating sblx245v correspondant à l'ID individuel (si les jeux n'ont pas été évalués, le résultat devrait renvoyer une valeur nulle des champs des deux dernières tables). Maintenant le problème auquel je suis confronté est le résultat qui ne sort pas comme prévu (certains jeux n'ont pas été notés apparaissent alors que d'autres ne sont pas), pouvez-vous les gars vérifier ma requête et me dire où je me trompe si oui ... Merci

+2

ne devriez-vous pas être grouper par game_data.game_id? –

+0

Cet homme whamps, je l'ai juste négligé ... Merci qui l'a fait – halocursed

Répondre

2

Vous ne devriez pas utiliser la colonne game_ratingstblx245v.game_id dans votre GROUP BY, car il pourrait être NULL quand il n'y a pas d'évaluation pour un identifiant de jeu donné. Utilisez game_data.id à la place.

Voilà comment j'écrire la requête:

SELECT g.id, g.name, 
     AVG(x.rating) AS avg_user_rating, 
     COUNT(DISTINCT x.userid) AS user_count, 
     AVG(r.critic_rating) AS avg_critic_rating, 
     COUNT(DISTINCT r.critic) AS critic_count 
FROM game_data g 
LEFT JOIN game_ratingstblx245v x ON (x.game_id = g.id) 
LEFT JOIN game_ratings r   ON (r.game_id = g.id) 
WHERE g.release_date < NOW() 
GROUP BY g.id 
ORDER BY g.release_date DESC, g.name; 

Notez que bien que cette requête produit un produit cartésien entre x et r, il ne touche pas le calcul des notes moyennes. Sachez à l'avenir que si vous faites SUM() ou COUNT(), les calculs pourraient être exagérés par un produit cartésien non intentionnel.

+0

Merci Bill pour les infos supplémentaires vous êtes toujours le premier à m'aider .... Sur une note de côté, je ne comprends pas ce que vous signifie par produit cartésien? – halocursed

+1

Un produit cartésien est un produit dans lequel chaque ligne d'une table est combinée à chaque ligne de la deuxième table. Supposons que vous ayez 10 lignes correspondantes dans la première table et 12 lignes correspondantes dans la seconde table. Si aucune condition ne limite les conditions de correspondance entre les deux, vous obtiendrez 120 lignes dans le résultat. Ce que cela signifie dans une requête comme la vôtre, c'est que les lignes de chaque table de notation se répètent sans le vouloir. Ce serait un problème si vous faisiez COUNT() ou SUM(). –

+1

Pour voir le produit cartésien en action, essayez votre requête sans GROUP BY, et affichez les colonnes 'rating' au lieu de calculer l'AVG(). Vous verrez beaucoup de lignes répétées. –