Mysql 根据加入结果选择订单(对上次发送的邮件进行对话排序)

Mysql 根据加入结果选择订单(对上次发送的邮件进行对话排序),mysql,sql,hibernate,select,Mysql,Sql,Hibernate,Select,我正在Hibernate中为消息传递组件创建SQL查询。我的想法是查询以获取用户的对话,按上次发送消息的日期排序 我有两张桌子: 对话 消息 在我的select查询中,我正在尝试类似的操作,但在最后发送的消息上从未发生排序 String sql = "SELECT * FROM conversations " + "JOIN messages ON messages.conversation_id = conversations.id "+

我正在Hibernate中为消息传递组件创建SQL查询。我的想法是查询以获取用户的对话,按上次发送消息的日期排序

我有两张桌子:

对话


消息


在我的select查询中,我正在尝试类似的操作,但在最后发送的消息上从未发生排序

String sql =
            "SELECT * FROM conversations " +
            "JOIN messages ON messages.conversation_id = conversations.id "+
            "WHERE (conversations.creator_id = :userId OR conversations.to_id = :userId)" +
            "GROUP BY messages.conversation_id "+
            "ORDER BY messages.created DESC";

该问题是由于对
GROUPBY
子句的行为进行了特定于MySQL的扩展。其他数据库将抛出一个错误。。。类似于选择列表中的on aggregate“。(如果在sql模式中只包含\u FULL\u GROUP\u BY,我们可以让MySQL抛出类似的错误。)

表达式
messages.created
的问题在于引用了GROUP BY中不确定行中的值。ORDER BY操作发生在GROUP BY操作之后的处理中

要获取为每个组创建的“最新”,请使用聚合表达式
MAX(messages.created)

从同一行中获取其他值要复杂一些

假设创建的
在给定的
对话id
组中是唯一的(或者,如果不能保证它不是唯一的,您可以为创建的
返回多个具有相同值的行)

要获取为每个
会话创建的最新
id

SELECT lm.conversation_id
     , MAX(lm.created) AS created
  FROM conversation lc
  JOIN message lm
    ON lm.conversation_id = lc.id
 WHERE (lc.creator_id = :userId OR lc.to_id = :userId)
 GROUP BY lm.conversation_id
您可以将其用作内联视图,以获取最新创建的
的整行

SELECT c.*
     , m.*
  FROM ( SELECT lm.conversation_id
              , MAX(lm.created) AS created
           FROM conversation lc
           JOIN message lm
             ON lm.conversation_id = lc.id
          WHERE (lc.creator_id = :userId OR lc.to_id = :userId)
          GROUP BY lm.conversation_id
       ) l
  JOIN conversation c
    ON c.id = l.conversation_id
  JOIN messages m
    ON m.conversation_id = l.conversation_id
   AND m.created         = l.created
 WHERE (c.creator_id = :userId OR c.to_id = :userId)
注:

您可以添加一个
orderby
子句,以便按照需要对返回的行进行排序

外部查询中的
WHERE
子句可能是多余的,不必要的


我们宁愿避免使用
SELECT*
,而宁愿显式列出要返回的表达式。

问题是由于对
GROUP BY
子句的行为进行了特定于MySQL的扩展。其他数据库会抛出错误……类似于SELECT list中的“聚合”。(我们可以让MySQL抛出类似的错误,如果我们在sql模式中只包含完整的组。)

表达式
messages.created
的问题在于引用了GROUP BY中不确定行中的值。ORDER BY操作发生在GROUP BY操作之后的处理中

要获取为每个组创建的“最新”,请使用聚合表达式
MAX(messages.created)

从同一行中获取其他值要复杂一些

假设创建的
在给定的
对话id
组中是唯一的(或者,如果不能保证它不是唯一的,您可以为创建的
返回多个具有相同值的行)

要获取为每个
会话创建的最新
id

SELECT lm.conversation_id
     , MAX(lm.created) AS created
  FROM conversation lc
  JOIN message lm
    ON lm.conversation_id = lc.id
 WHERE (lc.creator_id = :userId OR lc.to_id = :userId)
 GROUP BY lm.conversation_id
您可以将其用作内联视图,以获取最新创建的
的整行

SELECT c.*
     , m.*
  FROM ( SELECT lm.conversation_id
              , MAX(lm.created) AS created
           FROM conversation lc
           JOIN message lm
             ON lm.conversation_id = lc.id
          WHERE (lc.creator_id = :userId OR lc.to_id = :userId)
          GROUP BY lm.conversation_id
       ) l
  JOIN conversation c
    ON c.id = l.conversation_id
  JOIN messages m
    ON m.conversation_id = l.conversation_id
   AND m.created         = l.created
 WHERE (c.creator_id = :userId OR c.to_id = :userId)
注:

您可以添加一个
orderby
子句,以便按照需要对返回的行进行排序

外部查询中的
WHERE
子句可能是多余的,不必要的



我们更愿意避免使用
SELECT*
,而更愿意显式列出要返回的表达式。

@scaisEdge-在MySQL中不正确。此外,不适用,因为
*
正在选择推荐选择表中的所有列。*但仍然相同results@scaisEdge:该语句绝对不正确。SQL不允许您可以按不在选择列表中的表达式进行排序(可能某些数据库有这种非标准限制,但MySQL或Oracle肯定没有这种情况)为什么你要按对话进行分组?是不是每次对话只会收到一条消息?@spencer7593实际上这
从t ORDER by c3中选择不同的c1,c2;
是非法的,在MySQL的wierdo
groupby
中也是非法的,但是whatever@scaisEdge-在MySQL中不正确。此外,由于
*正在选择推荐选择表中的所有列。*但仍然相同results@scaisEdge:该语句绝对不正确。SQL确实允许您按不在选择列表中的表达式排序。(某些数据库可能有此非标准限制,但MySQL或Oracle肯定没有。)为什么你要按对话进行分组?是不是每次对话只会收到一条消息?@spencer7593实际上,这
从t ORDER by c3中选择不同的c1,c2;
是非法的,而且在MySQL的wierdo
group by
中也应该是非法的,但这可能是OP想要的,但他们可能刚刚得到了想要
SELECT*FROM()t order by created
有趣的是,在创建日期加入的方式…将对此进行一次尝试。谢谢Spencer…这看起来像是我想要的need@ConradFrix:这可能是OP想要的。但通常像这样的问题,OP想要的是“最新的”每个对话都有一条消息,并且希望在分组之前应用ORDER BY。这不是SQL的工作方式。感谢Spencer,这确实是正确的答案。我通过几个小调整成功地实现了它。干杯!我投了更高的票,因为这可能是OP想要的,但他们可能只是想要
SELECT*FROM()t order by created
有趣的是,在创建日期加入的方式…将对此进行一次尝试。谢谢Spencer…这看起来就是我想要的need@ConradFrix:这可能是OP想要的。但通常像这样的问题,OP想要的是“最新的”消息,并希望在分组之前应用ORDER BY。SQL不是这样工作的。谢谢Spencer,这确实是正确的答案。I h