MYSQL:唯一消息线程

时间:2018-08-16 05:55:53

标签: mysql group-by

我有一个消息表,其中包含

  

message_id,message_to_id,message_from_id,message_body,project_id。

我想要一个特定用户的消息线程列表。 消息线程应具有字段message_to_id,message_from_id和project_id的唯一组合。

之前我在project_id上使用group by,但是我不想让他们在项目上进行分组。

methods: {

    onSubmit(){

        var formData = this.toFormData(this.$data); 

        axios.post('/projects', formData)
        .then(response => alert("success"))
        .catch(error => alert("inv") );
    },

    toFormData: function(obj){
        var form_data = new FormData();
        for(var key in obj ){
            form_data.append(key, obj[key]);
        }
        return form_data;
    }

}

这没有按预期进行。

SELECT * FROM message
WHERE message_to = '{$user_id}' OR message_from = '{$user_id}'
GROUP BY project

这向我显示了我不想要的message_from和message_to的组合。

我希望在单个项目中按用户组合使用消息线程。

  

样本数据

SELECT * 
FROM message 
WHERE message_to = '{$user_id}' 
GROUP BY message_from 
UNION 
SELECT * 
FROM message 
WHERE message_from = '{$user_id}' 
GROUP BY message_to
  

我想要的

message_id | message_from_id | message_to_id | project_id | message _body
1          |  283            |  284          | 4          | Hello         
2          |  284            |  283          | 4          | Hi            
3          |  285            |  283          | 4          | Hey there!    
4          |  283            |  285          | 4          | Greetings     
5          |  283            |  284          | 6          | Cool! 

i.e忽略message_from_id和message_to_id的排序,但与project_id一起应该是唯一的。

2 个答案:

答案 0 :(得分:0)

正确的答案是忽略message_to和message_from的组合,并给出不同的组合。

SELECT DISTINCT 
    CASE WHEN message_from_id < message_to_id 
    THEN message_from_id 
    ELSE message_to_id END as message_from_id, 
    CASE WHEN message_from_id < message_to_id 
    THEN message_to_id 
    ELSE message_from_id END as message_to_id, 
    project 
FROM message 
WHERE message_to_id = '{$user_id}' OR message_from_id = '{$user_id}'

这样,它可以在没有“分组依据”的情况下工作。

但是此解决方案的问题是我无法获得任何类似send_at的非区别列(我在这里没有提到)。

答案 1 :(得分:0)

我使用ON或排名方法(ROW_NUMBERDENSE_RANK)提出了一种完全不同的解决方案,尽管它与所有SQL版本都不兼容,但我发现JOIN种方法似乎可以胜任。

这是我的结果:

SELECT message.message_id, message_to_id, message.message_from_id, message.project_id, message.message_body FROM 
  message
INNER JOIN
  (
  SELECT MIN(message_id) message_idMIN FROM message WHERE message_to_id = 283 GROUP BY project_id, message_to_id
    UNION 
  SELECT MIN(message_id) message_idMIN FROM message WHERE message_from_id = 283 GROUP BY project_id, message_from_id
  ) message_group
ON message.message_id = message_group.message_idMIN;

在这里查看小提琴:http://sqlfiddle.com/#!9/ef36a1/32