我正在尝试返回编写一个只返回第一个结果的查询,其中someid(第一个案例的结果)= X - 并忽略其中someid = X的后续结果。我将如何更改以下查询以实现该目标?
以下是我目前正在使用的内容:
SELECT DISTINCT CASE WHEN $userid != senderid THEN senderid ELSE GROUP_CONCAT(receivers.id SEPARATOR ', ') END someid,
CASE WHEN $userid != senderid THEN senders.username ELSE GROUP_CONCAT(receivers.username SEPARATOR ', ') END somename,
messages.body,
messages.time
FROM messages
LEFT JOIN messages_recipients AS recipients ON messages.id = recipients.messageid
LEFT JOIN users AS senders ON messages.senderid = senders.id
LEFT JOIN users AS receivers ON recipients.userid = receivers.id
WHERE recipients.userid = $userid
OR messages.senderid = $userid
GROUP BY messages.id
ORDER BY messages.time DESC
答案 0 :(得分:2)
根据您评论中的信息,我再次尝试了这一点。
我非常亲力亲为,所以虽然我可以概念化会发生什么,但直到我开始摆弄时我都不确定。
所以,让我们从数据开始。根据我们谈到的内容,我创建了三个表:
用户强> 的
id user_name
1 Walker
2 John
3 Kate
的消息强> 的
id senderid body time
1 1 ignored 1 2010-04-01 00:00:00.000
2 1 ignored 2 2010-04-02 00:00:00.000
3 3 ignored 3 2010-04-03 00:00:00.000
4 1 msg A to john and kate 2010-04-10 00:00:00.000
5 3 msg b from kate to walker and john 2010-04-11 00:00:00.000
*的 messages_recipients * 强>
id messageid userid
1 1 2
2 1 3
3 2 2
4 3 1
5 4 2
6 4 3
7 5 1
8 5 2
数据的定制方式使得(Walker)在4月份与John和Kate一起发送和接收消息。
您可以通过运行以下sql语句来查看这些消息的列表:
SELECT
u2.user_name AS Sender,
u1.user_name AS Receiver,
m.body,
m.time
FROM
messages m
JOIN
messages_recipients mr ON m.id = mr.messageid
JOIN
users u1 ON mr.userid = u1.id
JOIN
users u2 ON m.senderid = u2.id
ORDER BY
time DESC
现在,我们有了测试场景,这个棘手的部分:返回你(Walker)和John和Kate之间最近的沟通信息。我有一个相当长的SQL语句,不可否认,我不是最好的创建这些,但我认为这仍然有效:
BEGIN
DECLARE @UserId INT = 1
--A. Main Query
SELECT
CASE
WHEN mtemp.senderid = 1 --@UserId
THEN
CONCAT('Message To: ', receivers.user_name)
ELSE
CONCAT('Message From: ' , senders.user_name)
END AS MessageType,
mtemp.body,
mtemp.time
FROM
messages mtemp
INNER JOIN users senders ON
mtemp.senderid = senders.id
INNER JOIN
(
--B. Inner Query determining most recent message (based on time)
-- between @UserID and the person @UserID
-- Communicated with (either as sender or receiver)
select userid,max(maxtime) as maxmaxtime from
(
--C.1. First part of Union Query Aggregating sent/received messages on passed @UserId
SELECT
m2.body,
kk.*
FROM
`messages` m2 INNER JOIN
(
SELECT DISTINCT
userid,
MAX(m.time) AS MaxTime
FROM
messages m INNER JOIN
messages_recipients mr ON m.id = mr.messageid AND
m.senderid = 1 --@UserId
GROUP BY
mr.userid
) kk on m2.time = kk.MaxTime and m2.senderid = 1 --@UserId
UNION
--C.2. Second part of Union Query Aggregating sent/received messages on passed @UserId
SELECT
m1.body,
jj.*
FROM
`messages` m1 INNER JOIN
----C.2a. Inner most query of users users who sent message to userid
(SELECT DISTINCT
senderid as userid,
MAX(m.time) AS MaxTime
FROM
messages m INNER JOIN
messages_recipients mr ON m.id = mr.messageid AND
mr.userid = 1 --@UserId
GROUP BY
m.senderid) jj on m1.time = jj.MaxTime and m1.senderid = jj.userid
) MaximumUserTime
group by
MaximumUserTime.userid
) AggregatedData on mtemp.time = AggregatedData.maxmaxtime
INNER JOIN users receivers on AggregatedData.userid = receivers.id
ORDER BY `time` DESC
END
要在phpMyAdmin中测试,您还必须删除注释和开始/结束声明语句。我只是想发布这个,好像它会在一个程序中查找。
该查询假设您不会同时在同一用户发送和接收不同的消息;发生这种情况的可能性似乎非常小,所以我希望这可行。
当我运行此查询时,我得到以下结果:
MessageType body time
Message From: Kate msg b from kate to walker and john 2010-04-11 00:00:00.000
Message To: John msg A to john and kate 2010-04-10 00:00:00.000
这是与Walker沟通的所有用户中有关Walker的最新通讯。
希望有所帮助。
答案 1 :(得分:1)
在这种情况下,子查询可能会起作用(虽然它的表现可能不是一个很好的选择):
SELECT DISTINCT CASE WHEN $userid != senderid THEN senderid ELSE GROUP_CONCAT(receivers.id SEPARATOR ', ') END someid,
CASE WHEN $userid != senderid THEN senders.username ELSE GROUP_CONCAT(receivers.username SEPARATOR ', ') END somename,
messages.body,
messages.time
FROM messages
INNER JOIN
(
SELECT m.senderId, m.receiverId, MAX(m.time) AS MyMaxTime FROM messages GROUP BY m.senderId, m.receiverId
) myLittleQuery
ON messages.senderid = myLittleQuery.senderid AND messages.senderid = myLittleQuery.receiverId AND messages.time = myLittleQuery.MyMaxTime
LEFT JOIN messages_recipients AS recipients ON messages.id = recipients.messageid
LEFT JOIN users AS senders ON messages.senderid = senders.id
LEFT JOIN users AS receivers ON recipients.userid = receivers.id
WHERE recipients.userid = $userid
OR messages.senderid = $userid
GROUP BY messages.id
ORDER BY messages.time DESC
自从我进入MySQL领域已经有一段时间了,所以我的语法很可能已经关闭了。然而,它的要点就在那里。
此外,根据您要检索的内容,您也可以放弃DISTINCT和CASE语句。