重写这个sql查询

时间:2010-01-25 02:25:35

标签: sql sql-server tsql

我编写了一个获取未读消息的SQL查询,但我认为我可以改进代码(速度和可读性)。第一个选择用于COUNT功能,第二个选择用于根据conversation_id对消息进行分组,最后的嵌套选择用于选择最后的消息。

请给我建议。提前谢谢。

SELECT COUNT(*) as unreaded FROM ( 
  SELECT id 
  FROM (
    SELECT id, conversation_id
    FROM messages
    WHERE to_id = ?
    AND readed = 0
    and NOT hide_from = ?
    ORDER BY sended DESC
  ) AS temp_messages 
  GROUP BY conversation_id
) as temp_messages2

3 个答案:

答案 0 :(得分:2)

按原样查询无效 - 您需要定义GROUP BY中未包含在聚合中的所有列。

目前尚不清楚,但如果您想要一系列独特的对话,请使用:

SELECT COUNT(DISTINCT m.conversation_id) AS unread
  FROM MESSAGES m
 WHERE m.to_id = ?
   AND m.readed = 0
   AND m.hide_from != ?

...否则,请使用:

SELECT COUNT(*) AS unread
  FROM MESSAGES m
 WHERE m.to_id = ?
   AND m.readed = 0
   AND m.hide_from != ?
  • 子查询是不必要的
  • ORDER BY是浪费资源,因为它没有在最终输出中使用,也没有使用TOP
  • GROUP BY无效,因为MESSAGES.id不在列表

答案 1 :(得分:0)

这甚至有用吗? id不在聚合中,因此您无法通过会话选择ID组。

话虽如此,您正在寻找有未读消息的对话吗?

select count(distinct conversation_id) from message
 WHERE to_id = ? 
   AND readed = 0 
   and NOT hide_from = ? 

应该能满足您的需求

答案 2 :(得分:0)

SELECT COUNT(*) as unreaded FROM ( 
  SELECT id, conversation_id
  FROM messages
  WHERE to_id = ?
  AND readed = 0
  and NOT hide_from = ?
  GROUP BY conversation_id
) as temp_messages2

您不需要order by子句,可以将group by子句移动到内部子查询中。