2010-01-25 5 views
3

J'ai écrit une requête SQL qui reçoit des messages non lus, mais je pense que je peux améliorer le code (vitesse et la lisibilité). La première sélection est pour la fonction COUNT, la seconde pour le groupement des messages selon conversation_id, et la sélection imbriquée finale pour la sélection des derniers messages.réécrivant cette requête SQL

S'il vous plaît donnez-moi des suggestions. Merci d'avance.

SELECT COUNT(*) as unreaded FROM ( 
    SELECT id 
    FROM (
    SELECT id, conversation_id 
    FROM messages 
    WHERE to_id = ? 
    AND readed = 0 
    and NOT hide_from = ? 
    ORDER BY sended DESC 
) AS temp_messages 
    GROUP BY conversation_id 
) as temp_messages2 
+5

« non lu », et non « unreaded » et aussi « envoyé » au lieu de « ENVOYÉE ». Ceux-ci amélioreraient la lisibilité au moins;) –

+0

Voulez-vous que le nombre total de messages non lus compte? Ou 'non lu, id, conversation_id'? qu'est-ce que 'id'? Ce sera mieux si vous postez ddl, l'échantillon et la sortie attendue. –

Répondre

2

La requête en l'état ne fonctionne pas - vous devez définir toutes les colonnes qui ne sont pas enveloppés dans des agrégats dans le GROUP BY.

On ne sait pas, mais si vous voulez un compte de conversations uniques, utilisez:

SELECT COUNT(DISTINCT m.conversation_id) AS unread 
    FROM MESSAGES m 
WHERE m.to_id = ? 
    AND m.readed = 0 
    AND m.hide_from != ? 

... sinon, utilisez:

SELECT COUNT(*) AS unread 
    FROM MESSAGES m 
WHERE m.to_id = ? 
    AND m.readed = 0 
    AND m.hide_from != ? 
  • Les sous-requêtes ne sont pas nécessaires
  • le ORDER BY est un gaspillage de ressources car il est pas utilisé dans la sortie finale, ni est TOP utilisé
  • Le GROUP BY ne fonctionnera pas parce que MESSAGES.id n'est pas dans la liste des colonnes
+0

J'upvoted, mais je pense à la façon dont il a écrit sa requête que le '' * peut-être besoin d'être un 'DISTINCT id' ... il semble * * comme c'est ce qu'il est après, bien qu'il soit un peu difficile à dire . – Aaronaught

+0

Je pense réellement qu'il veut distinct_id_de conversation, à cause de ce groupe mystérieux dans la sous-requête – Jimmy

0

Est-ce que cela fonctionne même? L'identifiant n'est pas agrégé, vous ne pouvez donc pas sélectionner un groupe d'ID par conversation.

Cela étant dit, vous cherchez des conversations qui ont des messages non lus?

select count(distinct conversation_id) from message 
WHERE to_id = ? 
    AND readed = 0 
    and NOT hide_from = ? 

devrait vous obtenir ce dont vous avez besoin

0
SELECT COUNT(*) as unreaded FROM ( 
    SELECT id, conversation_id 
    FROM messages 
    WHERE to_id = ? 
    AND readed = 0 
    and NOT hide_from = ? 
    GROUP BY conversation_id 
) as temp_messages2 

Vous n'avez pas besoin de la clause order by, et vous pouvez déplacer la clause group by dans la sous-requête interne.

+0

Ne fonctionne pas - doit être 'GROUP BY id, conversation_id' parce qu'il n'y a pas d'agrégat sur la colonne' id'. Cela fonctionnerait si la requête était exécutée sur MySQL, bien que je doute que les résultats soient corrects. –