我有一个用户表和一个消息表。
在消息表(名为messaggi
)中,有msg_to
和msg_from
,他们的消息(msg_text
)和msg_date
(这是一个日期和时间)。
我试图获得一个列表:
来自utenti
表
对于邮件为SENT或RECEIVED的每个用户,最后应显示
隐藏非自我人的信息(在这种情况下为id_utente 1 = self)。
这是我提出的,但我继续获取所有消息或双重用户,等等......
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_text
和msg_date
答案 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)