2017-03-05 3 views
0

ceci est ma requête:Mysql - sélectionnez la dernière ligne pour chaque utilisateur

SELECT msgId as `ID`,msgFromUserId , msgToUserId , 
      DATE_FORMAT(msgDate,'%d/%m/%y %H:%i') as `time` , MID(msgText,1,30) as `text` , 
      (CASE WHEN (msgFromUserId=292646) then b.user_login else a.user_login END) as `sender` 
      FROM tbl_messages inner join wp_users as a on tbl_messages.msgFromUserId=a.ID 
      inner join wp_users as b on tbl_messages.msgToUserId=b.ID 
      inner join tbl_forum_users u1 on tbl_messages.msgFromUserId=u1.user_ID 
      inner join tbl_forum_users u2 on tbl_messages.msgToUserId=u2.user_ID 
where (msgFromUserId=292646 or msgToUserId=292646) 
and tbl_messages.msgId in (SELECT max(msgId) FROM tbl_messages GROUP BY msgFromUserId, msgToUserId) 
order by msgId desc 

je reçois ceci:

result table

Je ne veux pas la ligne de duplication. Procurez-vous la dernière ligne de la conversation entre les

+0

Vous pouvez faire est 'Order DESC' vous obtenez les rangées de l'ordre 'last to first' et ensuite' LIMIT 1' vous obtenez la seule dernière ligne ie. première rangée – Alen

+0

N'avez-vous pas un problème sérieux avec la définition de table et de colonne? les enregistrements 107 et 26 ont le même expéditeur. Ne devrait-il pas varier quand il y a un autre 'FromUserId'? – Whencesoever

+0

Pourquoi vous joignez 'tbl_forum_users'? Où utilisez-vous 'u1' et' u2'? –

Répondre

2

Une solution rapide pourrait être de changer votre sous-requête

SELECT max(msgId) FROM tbl_messages GROUP BY msgFromUserId, msgToUserId 

à

SELECT max(msgId) 
FROM tbl_messages 
GROUP BY LEAST(msgFromUserId, msgToUserId), GREATEST(msgFromUserId, msgToUserId) 

Cette volonté messages groupe 292646-1 et 1-292646 ensemble.

requête complète:

SELECT msgId as `ID`,msgFromUserId , msgToUserId , 
      DATE_FORMAT(msgDate,'%d/%m/%y %H:%i') as `time` , MID(msgText,1,30) as `text` , 
      (CASE WHEN (msgFromUserId=292646) then b.user_login else a.user_login END) as `sender` 
      FROM tbl_messages inner join wp_users as a on tbl_messages.msgFromUserId=a.ID 
      inner join wp_users as b on tbl_messages.msgToUserId=b.ID 
      inner join tbl_forum_users u1 on tbl_messages.msgFromUserId=u1.user_ID 
      inner join tbl_forum_users u2 on tbl_messages.msgToUserId=u2.user_ID 
where (msgFromUserId=292646 or msgToUserId=292646) 
and tbl_messages.msgId in (
    SELECT max(msgId) 
    FROM tbl_messages 
    GROUP BY LEAST(msgFromUserId, msgToUserId), GREATEST(msgFromUserId, msgToUserId) 
) 
order by msgId desc 

Pour améliorer les performances, vous devez également déplacer l'ID condition d'utilisateur dans la sous-requête:

SELECT max(msgId) 
FROM tbl_messages 
where (msgFromUserId=292646 or msgToUserId=292646) -- <-- here 
GROUP BY LEAST(msgFromUserId, msgToUserId), GREATEST(msgFromUserId, msgToUserId) 

Pour utiliser les index de la meilleure façon, vous devez utiliser un UNION ALL optimisation. Mais cela va regarder assez complexe:

SELECT max(msgId) 
FROM (
    SELECT msgToUserId as otherUserId, max(msgId) as msgId 
    FROM tbl_messages 
    WHERE msgFromUserId=292646 
    GROUP BY msgToUserId 

    UNION ALL 

    SELECT msgFromUserId as otherUserId, max(msgId) as msgId 
    FROM tbl_messages 
    WHERE msgToUserId=292646 
    GROUP BY msgFromUserId 
) sub 
GROUP BY otherUserId 

Notez que cette seule la sous-requête à utiliser dans la clause WHERE (tbl_messages.msgId in (...)).

Cette sous-requête peut également être utilisé comme une table dérivée, afin que nous puissions rejoindre avec tbl_messages:

SELECT msgId as `ID`, 
     msgFromUserId, 
     msgToUserId, 
     DATE_FORMAT(msgDate,'%d/%m/%y %H:%i') as `time`, 
     MID(msgText,1,30) as `text` , 
     (CASE WHEN (msgFromUserId=292646) then b.user_login else a.user_login END) as `sender` 
FROM (
    SELECT max(msgId) as msgId 
    FROM (
     SELECT msgToUserId as otherUserId, max(msgId) as msgId 
     FROM tbl_messages 
     WHERE msgFromUserId=292646 
     GROUP BY msgToUserId 
     UNION ALL 
     SELECT msgFromUserId as otherUserId, max(msgId) as msgId 
     FROM tbl_messages 
     WHERE msgToUserId=292646 
     GROUP BY msgFromUserId 
    ) sub 
    GROUP BY otherUserId 
) sub 
inner join tbl_messages on tbl_messages.msgId = sub.msgId 
inner join wp_users as a on tbl_messages.msgFromUserId=a.ID 
inner join wp_users as b on tbl_messages.msgToUserId=b.ID 
inner join tbl_forum_users u1 on tbl_messages.msgFromUserId=u1.user_ID 
inner join tbl_forum_users u2 on tbl_messages.msgToUserId=u2.user_ID 
order by tbl_messages.msgId desc 

Vous avez besoin des indices suivants pour soutenir la sous-requête:

tbl_messages(msgFromUserId, msgToUserId [, msgId]) 
tbl_messages(msgToUserId, msgFromUserId [, msgId])