获取最高值列行作为连接行

时间:2013-05-01 16:51:32

标签: sql left-join

我有SQL语句

SELECT * 
FROM `assocMessages`
LEFT JOIN `messageThreads` ON `messageThreads`.`threadID` = `assocMessages`.`threadID` 
LEFT JOIN `messages` ON `messageThreads`.`threadID` = `messages`.`threadID` 
WHERE `assocMessages`.`accountID` =1
GROUP BY `messageThreads`.`threadID` 
ORDER BY `messages`.`messageSent` DESC

用于获取当前用户与之关联的message threads列表。它还旨在获取与找到的message相关联的最新message threads,但是,它仅显示在找到的message thread上发送的第一条消息。我添加了语句ORDER BY messages.messageSent DESC,但无论它在哪里,或方向为ASCDESC,它都只显示发送的第一个message。有谁知道我能做什么?我试图将它保留在单个SQL语句中,以防止遇到n + 1选择问题。

修改

我刚刚尝试撤消表格,因此它最初有FROM messagesassocMessages表格稍后加入

修改

assocMessages:

+-----------+----------+
| accountID | threadID |
+-----------+----------+
| 1         | 1        |
+-----------+----------+
| 2         | 1        |
+-----------+----------+

messageThreads:

+----------+---------------------+
| threadID | threadCreatedOn     |
+----------+---------------------+
| 1        | 2013-05-01 12:00:00 |
+----------+---------------------+

消息:

+-----------+----------+-----------+-------------+---------------------+
| messageID | threadID | accountID | messageBody | messageSent         |
+-----------+----------+-----------+-------------+---------------------+
| 1         | 1        | 1         | First Hi    | 2013-05-01 12:00:00 |
+-----------+----------+-----------+-------------+---------------------+
| 2         | 1        | 2         | Second Hi   | 2013-05-01 12:01:00 |
+-----------+----------+-----------+-------------+---------------------+

因此,当查询时,它将返回一个线程列表(accountID 1已注册),最新的messagemessageID 2由accountID 2

返回的内容:

+-----------+----------+---------------------+-----------+-------------+---------------------+----------+-----------+
| accountID | threadID | threadCreated       | messageID | messageBody | messageSent         | threadID | accountID |
+-----------+----------+---------------------+-----------+-------------+---------------------+----------+-----------+
| 1         | 1        | 2013-05-01 12:00:00 | 1         | First Hi    | 2013-05-01 12:00:00 | 1        | 1         |
+-----------+----------+---------------------+-----------+-------------+---------------------+----------+-----------+

应该返回什么:

+-----------+----------+---------------------+-----------+-------------+---------------------+----------+-----------+
| accountID | threadID | threadCreated       | messageID | messageBody | messageSent         | threadID | accountID |
+-----------+----------+---------------------+-----------+-------------+---------------------+----------+-----------+
| 1         | 1        | 2013-05-01 12:00:00 | 2         | Second Hi   | 2013-05-01 12:01:00 | 1        | 2         |
+-----------+----------+---------------------+-----------+-------------+---------------------+----------+-----------+

如果我删除group by

,会返回什么
+-----------+----------+---------------------+-----------+-------------+---------------------+----------+-----------+
| accountID | threadID | threadCreated       | messageID | messageBody | messageSent         | threadID | accountID |
+-----------+----------+---------------------+-----------+-------------+---------------------+----------+-----------+
| 1         | 1        | 2013-05-01 12:00:00 | 2         | Second Hi   | 2013-05-01 12:01:00 | 1        | 2         |
+-----------+----------+---------------------+-----------+-------------+---------------------+----------+-----------+
| 1         | 1        | 2013-05-01 12:00:00 | 1         | First Hi    | 2013-05-01 12:00:00 | 1        | 1         |
+-----------+----------+---------------------+-----------+-------------+---------------------+----------+-----------+

第一个accountID是相同的,因为它们是从messageThreads关联返回的

最终编辑(暂时)

当我删除GROUP BY messageThreads.threadID时,它会显示每个帖子中的所有消息

2 个答案:

答案 0 :(得分:1)

我认为你问题的一部分是MySQL应用GROUP BY的方式。 MySQL extends the GROUP BY function允许从聚合函数和GROUP BY中排除选择列表中的项目。此扩展可能会导致意外结果。

我认为以下内容会为您提供所需的结果:

SELECT a.accountId,
  a.threadId,
  mt.threadCreatedOn,
  m.messageId,
  m.messageBody,
  m.messageSent,
  m.accountId messageAccountId
FROM `assocMessages` a
INNER JOIN `messageThreads` mt
  ON mt.`threadID` = a.`threadID` 
LEFT JOIN
(
  select m1.*
  from messages m1
  inner join
  (
    select max(messageSent) messageSent,
      threadId
    from messages
    group by threadid
  ) m2
    on m1.threadid = m2.threadid
    and m1.messageSent = m2.messageSent
) m
  ON mt.`threadID` = m.`threadID` 
WHERE a.`accountID` =1
ORDER BY m.`messageSent` DESC;

请参阅SQL Fiddle with Demo

答案 1 :(得分:0)

我对你实际要问的内容感到有些困惑,但请看一下:

SELECT `assocMessages`.*, `messageThreads`.`threadCreatedOn`, `messages`.`messageBody`, `messages`.`messageSent` 
FROM `assocMessages`
LEFT JOIN `messageThreads` ON `messageThreads`.`threadID` = `assocMessages`.`threadID`
LEFT JOIN `messages` ON `messageThreads`.`threadID` = `messages`.`threadID` AND `assocMessages`.`accountID`=`messages`.`accountID`
WHERE `assocMessages`.`accountID` =1
ORDER BY `messages`.`messageSent` DESC

这是你想要做的吗?我修改了消息

messageID   threadID    accountID   messageBody     messageSent
1           1           1           First Hi    2013-05-01 12:00:00
2           1           2           Second Hi   2013-05-01 12:01:00
3           1           1           Third Message   2013-05-01 12:02:00

,SQL查询结果为:

accountID   threadID    threadCreatedOn     messageBody     messageSent
1           1           2013-05-01 12:00:00     Third Message   2013-05-01 12:02:00
1           1           2013-05-01 12:00:00     First Hi    2013-05-01 12:00:00