I have a table in MySQL which holds conversations. These conversation are composed of messages. A single conversation looks like the table below.
Importance
and eId
's are only sometimes set. What I am trying to get from the table is the last message in the conversation ( messageId
= 4) but with the last set importance
and last set eId
.
So, from this table
+----------------+-----------+----------+----------+------------+-------+---------+
| conversationId | messageId | time | status | importance | eId | message |
+----------------+-----------+----------+----------+------------+-------+---------+
| 25 | 4 | 11:00:00 | feedback | NULL | NULL | d.. |
+----------------+-----------+----------+----------+------------+-------+---------+
| 25 | 3 | 10:00:00 | open | MEDIUM | NULL | c.. |
+----------------+-----------+----------+----------+------------+-------+---------+
| 25 | 2 | 09:00:00 | feedback | NULL | 123 | b... |
+----------------+-----------+----------+----------+------------+-------+---------+
| 25 | 1 | 08:00:00 | open | HIGH | NULL | a... |
+----------------+-----------+----------+----------+------------+-------+---------+
I need to get this result
+----------------+-----------+----------+----------+------------+-------+---------+
| conversationId | messageId | time | status | importance | eId | message |
+----------------+-----------+----------+----------+------------+-------+---------+
| 25 | 4 | 11:00:00 | feedback | MEDIUM | 123 | d.. |
+----------------+-----------+----------+----------+------------+-------+---------+
I can't get the query to work. Any help would be appriciated. Thanks.
This one is not necessarily the best solution as I had to create this in my local SQL Server (SQL fiddle was down when tried and I have no MySQL installed), also a "quick and dirty" query (means: there might be a better solution for your problem), but as I am keen to help I post it anyway.
If you happen to wait for another, possibly better solution from the community, I will not feel offended :) That is what I wanted to say :)
SELECT TOP 1 conversationId,messageId,RecTime,ConvStatus,
(
SELECT TOP 1 importance
FROM Conversations
WHERE importance IS NOT NULL
ORDER BY messageId DESC
) AS importance,
(
SELECT TOP 1 eId
FROM Conversations
WHERE eId IS NOT NULL
ORDER BY messageId DESC
) AS eId,
UsrMessage
FROM Conversations
ORDER BY messageId DESC
GO
If there is more than one conversationId in the table, and you want to get the desired result for all of the conversationIds at the same time, then I think you need to join 3 subqueries within subqueries. Something like the 3 below:
SELECT messages.conversationId, messages.messageId, messages.time, messages.status, messages.message
FROM messages
JOIN (
SELECT conversationId, MAX(messageId) as messageId
FROM messages
GROUP BY conversationId) as m2
ON (messages.messageId = m2.messageId);
SELECT messages.conversationId, messages.importance
FROM messages
JOIN (
SELECT conversationId, MAX(messageId) as messageId
FROM messages
WHERE importance IS NOT NULL
GROUP BY conversationId) as m3
ON (messages.messageId = m3.messageId);
SELECT messages.conversationId, messages.eId
FROM messages
JOIN (
SELECT conversationId, MAX(messageId) as messageId
FROM messages
WHERE eId IS NOT NULL
GROUP BY conversationId) as m4
ON (messages.messageId = m4.messageId);
The JOIN would look like this:
SELECT
main.conversationId,
main.messageId,
main.time,
main.status,
importance.importance,
eId.eId,
main.message
FROM (
SELECT messages.conversationId, messages.messageId, messages.time, messages.status, messages.message
FROM messages
JOIN (
SELECT conversationId, MAX(messageId) AS messageId
FROM messages
GROUP BY conversationId) AS m2
ON (messages.messageId = m2.messageId)
) AS main
JOIN (
SELECT messages.conversationId, messages.importance
FROM messages
JOIN (
SELECT conversationId, MAX(messageId) AS messageId
FROM messages
WHERE importance IS NOT NULL
GROUP BY conversationId) AS m3
ON (messages.messageId = m3.messageId)
) AS importance
JOIN (
SELECT messages.conversationId, messages.eId
FROM messages
JOIN (
SELECT conversationId, MAX(messageId) AS messageId
FROM messages
WHERE eId IS NOT NULL
GROUP BY conversationId) AS m4
ON (messages.messageId = m4.messageId)
) AS eId
ON (
main.conversationId = importance.conversationId
AND main.conversationId = eId.conversationId
);
Here's an sqlfiddle: http://sqlfiddle.com/#!2/857aa/38 . This assumes that messageId is unique. If it is not unique, then you need to join on messageId AND conversationId.
Maybe a bit oldschool but should do the trick :
SELECT c.conversationId as convId, max(c.messageId), t.time, s.status, i.importance, e.eId, c.message
FROM convs c,
(SELECT conversationId, max(time) AS time FROM convs) t,
(SELECT conversationId, status FROM convs WHERE status IS NOT NULL ORDER BY messageId DESC) s,
(SELECT conversationId, importance FROM convs WHERE importance IS NOT NULL ORDER BY messageId DESC) i,
(SELECT conversationId, eId FROM convs WHERE eId IS NOT NULL ORDER BY messageId DESC) e
WHERE 1=1
AND t.conversationId = c.conversationId
AND s.conversationId = c.conversationId
AND i.conversationId = c.conversationId
AND e.conversationId = c.conversationId
GROUP BY c.conversationId
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.