Where子句影响Count()但不影响返回的结果数

时间:2012-05-21 01:27:12

标签: sql sql-server

假设我有两张桌子:

会员

------------------------
| user_id | first_name |
------------------------

消息

--------------------------------------------------
| sender_id | recipient_id | message_type | body |
--------------------------------------------------

我想创建一个返回:

的查询
---------------------------------------------
| user_id | first_name | number_of_messages |
---------------------------------------------

number_of_messages应该只计算某种类型的消息message_type = 0,但是我仍然希望在结果集中包含不发送任何类型消息的成员。

这就是我目前所拥有的:

SELECT [user_id], [first_name], COUNT(sender_id) as number_of_messages
FROM [Member]
    FULL OUTER JOIN [Message] ON user_id = sender_id
where message_type = 0
GROUP BY [Member].[user_id], [first_name]
ORDER BY number_of_messages DESC

此查询的问题是未发送类型0消息的任何成员都不会包含在结果集中。所以我想使用message_type = 0子句来减少number_of_messages,但我不希望它影响返回的结果数。

如果我可以对您的查询进行任何其他优化,请随时对其进行评论。

2 个答案:

答案 0 :(得分:2)

使用OUTER JOIN:

   SELECT [user_id], [first_name], COUNT(m.sender_id) as number_of_messages
     FROM [Member]
LEFT JOIN [Message] m ON user_id = m.sender_id
                     AND m.message_type = 0
 GROUP BY [Member].[user_id], [first_name]
 ORDER BY number_of_messages DESC

请注意,我的查询包含JOIN条件中的message_type过滤器 - 不在WHERE子句中。使用OUTER join语法放置很重要 - 在JOIN子句中,在JOIN之前应用条件。在JOIN之后应用WHERE标准,并且可以给出不同的结果。

答案 1 :(得分:0)

如果你想要包含那些没有这样的消息的成员,你只需删除m.message_type = 0,我没有看到另一种方式。选择所有人,然后使用IF子句根据需要过滤结果。

另一种解决方案可能是为每个类型为0的用户创建一个虚拟条目,并在使用它们时过滤掉这些消息。