用户的MSYQL SELECT和群组对话并显示上一条消息

时间:2018-04-20 12:50:25

标签: mysql greatest-n-per-group

我有一个用户表和一个消息表。

在消息表(名为messaggi)中,有msg_tomsg_from,他们的消息(msg_text)和msg_date(这是一个日期和时间)。

我试图获得一个列表:

  1. 来自utenti

  2. 的所有用户
  3. 对于邮件为SENT或RECEIVED的每个用户,最后应显示

  4. 隐藏非自我人的信息(在这种情况下为id_utente 1 = self)。

  5. 这是我提出的,但我继续获取所有消息或双重用户,等等......

    SELECT CONCAT(LEFT(u.fname, 1), LEFT(u.lname, 1)) AS iniziali,
           u.email,
           u.color,
           CONCAT(u.fname, " ", u.lname) AS full_name,
           MAX(m.msg_date) AS msg_date,
           m.msg_text
    FROM utenti u
         INNER JOIN messaggi m ON m.msg_to = u.id_utente
    WHERE m.msg_to = 1
    GROUP BY m.msg_to,
             m.msg_from
    UNION
    SELECT CONCAT(LEFT(u2.fname, 1), LEFT(u2.lname, 1)) AS iniziali,
           u2.email,
           u2.color,
           CONCAT(u2.fname, " ", u2.lname) AS full_name,
           "",
           ""
    FROM utenti u2
    WHERE u2.id_utente NOT IN
    (
        SELECT id_utente
        FROM utenti u
             INNER JOIN messaggi m ON m.msg_to = u.id_utente
        WHERE m.msg_to = 1
              AND u.id_utente = 1
        GROUP BY m.msg_to,
                 m.msg_from
    );
    

    这是一个小提琴:

    http://sqlfiddle.com/#!9/106319/1

    我想要的输出应该是:

    | iniziali |       email |  color |    full_name |            msg_date |       msg_text |
    |----------|-------------|--------|--------------|---------------------|----------------|
    |       BV |  456@me.com | (null) |   Bill Villa | 2018-04-20 12:29:20 | Msg 2 (1 to 2) |
    |       MG |  789@me.com | (null) |    Max Gazze | 2018-04-09 14:59:39 | Msg 1 (3 to 1) |
    |       JB |  101@me.com | (null) |    Jack Blue |                     |                |
    

    在这种情况下,我是id#1我只看到从ME和TO ME发送的消息,并且对于每个用户,我只看到最后一个接收或发送的消息。像WhatsApp,Facebook Messanger,Telegram等......你会看到每个人发送/接收的联系人和最后一条消息。

    不显示与其他用户(即用户2到用户3)之间的消息。

    正如你所看到的,我没有在用户列表中看到自己(id#1),而对于Jack Blue我只看到他的名字e没有消息,因为没有消息从用户1和4发送过。所以我最后得到一个用户列表,对于每个用户,我都会看到最近的消息(已发送或已接收),但在没有消息的情况下,我只看到空闲msg_textmsg_date

    的用户

3 个答案:

答案 0 :(得分:1)

好的,所以我认为我可能有一个解决方案。我用你的小提琴测试它似乎工作正常。

通过组合MySQL GROUP BY行为(仅返回组中的第一个)和ORDER BY,我们可以实现所需的结果,尽管最终结果按名称排序。 (编辑:只需将ORDER BY msg_date desc添加到SQL查询的末尾,然后按日期排序)

编辑:我已将查询更改为id_utente上的分组,并按msg_date排序。它适用于小提琴,它正在运行MySQL version 5.6

SELECT * FROM ((SELECT CONCAT(LEFT(u.fname , 1), LEFT(u.lname , 1)) as iniziali, 
        u.id_utente,
        u.email, 
        u.color, 
        CONCAT(u.fname, " ", u.lname) as full_name, 
        m.msg_date,
        m.msg_text 
  FROM utenti u
  LEFT JOIN messaggi m ON m.msg_to = u.id_utente
  WHERE (m.msg_from = 1) OR m.msg_date is NULL)
  UNION
  (SELECT CONCAT(LEFT(u.fname , 1), LEFT(u.lname , 1)) as iniziali, 
        u.id_utente,
        u.email, 
        u.color, 
        CONCAT(u.fname, " ", u.lname) as full_name, 
        m.msg_date,
        m.msg_text 
  FROM utenti u
  LEFT JOIN messaggi m ON m.msg_from = u.id_utente
  WHERE (m.msg_to = 1) OR m.msg_date is NULL)
  ORDER BY id_utente, msg_date desc) st1
  WHERE id_utente != 1
  GROUP BY id_utente ORDER BY msg_date desc

在你的小提琴中,这将返回

iniziali | id_utente |  email      | color  | full_name  | msg_date             | msg_text
---------+-----------+-------------+--------+------------+----------------------+-------------------
BV       |         2 | 456@me.com  | (null) | Bill Villa | 2018-04-20T12:29:20Z | Msg 2 (1 to 2)
MG       |         3 | 789@me.comm | (null) | Max Gazze  | 2018-04-09T14:59:39Z | Msg 1 (3 to 1)
JB       |         4 | 101@me.comm | (null) | Jack Blue  | (null)               | (null)

答案 1 :(得分:1)

这是我对此的尝试,我使用了一个联合,第一部分是针对那些来自/到id 1的消息的用户,而第二部分是针对那些没有消息的用户。

SELECT CONCAT(LEFT(u.fname, 1), LEFT(u.lname, 1)) AS iniziali,
   u.email,
   u.color,
   CONCAT(u.fname, " ", u.lname) AS full_name,
   u.id_utente,
   m.msg_date,
   m.msg_text
FROM utenti u, messaggi m
WHERE (m.msg_to = u.id_utente OR m.msg_from = u.id_utente)
AND (m.msg_to = 1 and m.msg_from != 1 OR m.msg_to != 1 and m.msg_from = 1)
AND m.msg_date = (SELECT MAX(m2.msg_date) FROM messaggi m2 WHERE (m2.msg_to = u.id_utente AND m2.msg_from = 1) OR (m2.msg_from = u.id_utente AND m2.msg_to = 1))
UNION ALL
SELECT CONCAT(LEFT(u.fname, 1), LEFT(u.lname, 1)) AS iniziali,
   u.email,
   u.color,
   CONCAT(u.fname, " ", u.lname) AS full_name,
   u.id_utente,
   '',
   ''
FROM utenti u
WHERE NOT EXISTS (SELECT * FROM messaggi m WHERE (m.msg_to = u.id_utente AND m.msg_from = 1) OR (m.msg_from = u.id_utente AND m.msg_to = 1))
AND u.id_utente != 1
ORDER BY msg_date DESC

答案 2 :(得分:1)

尽管你已经接受了答案,但我已经做出了努力,我也想发布这篇文章。此查询也将根据您提供的示例数据起作用。我使用了一个变量来测试不同的用户。

set @uid = 1;
select u1.id_utente as id,
    CONCAT(LEFT(u1.fname, 1), LEFT(u1.lname, 1)) AS iniziali,
    u1.email as email,
    u1.color as color,
    concat(u1.fname, ' ', u1.lname) as full_name, 
    m.msg_date as msg_date,
    m.msg_text as msg_text
from utenti u1
join utenti u2 
    on u1.id_utente != u2.id_utente and u2.id_utente = @uid
left join messaggi m
    on m.msg_to = u1.id_utente and m.msg_from = u2.id_utente or
       m.msg_to = u2.id_utente and m.msg_from = u1.id_utente
where m.msg_date = (select max(msg_date) 
                    from messaggi m2
                    where m2.msg_to = u1.id_utente and m2.msg_from = u2.id_utente or
                    m2.msg_to = u2.id_utente and m2.msg_from = u1.id_utente) or
      m.id_msg is null
group by u1.id_utente
order by msg_date desc

@uid = 1,输出

id  iniziali    email       color   full_name       msg_date                msg_text
2   BV          456@me.com  (null)  Bill Villa      2018-04-20T12:29:20Z    Msg 2 (1 to 2)
3   MG          789@me.com  (null)  Max Gazze       2018-04-09T14:59:39Z    Msg 1 (3 to 1)
4   JB          101@me.com  (null)  Jack Blue       (null)                  (null)

@uid = 2,输出

id  iniziali    email       color   full_name       msg_date                msg_text
1   JL          123@me.com  (null)  Joe Lombardi    2018-04-20T12:29:20Z    Msg 2 (1 to 2)
3   MG          789@me.com  (null)  Max Gazze       2018-04-09T15:03:44Z    Msg 1 (3 to 2)
4   JB          101@me.com  (null)  Jack Blue       (null)                  (null)

@uid = 3,输出

id  iniziali    email       color   full_name       msg_date                msg_text
2   BV          456@me.com  (null)  Bill Villa      2018-04-09T15:03:44Z    Msg 1 (3 to 2)
1   JL          123@me.com  (null)  Joe Lombardi    2018-04-09T14:59:39Z    Msg 1 (3 to 1)
4   JB          101@me.com  (null)  Jack Blue       (null)                  (null)

@uid = 4,输出

id  iniziali    email       color   full_name       msg_date                msg_text
1   JL          123@me.com  (null)  Joe Lombardi    (null)                  (null)
2   BV          456@me.com  (null)  Bill Villa      (null)                  (null)
3   MG          789@me.com  (null)  Max Gazze       (null)                  (null)