0

所以我有一个私人消息模型,其中包含以下列:sender_idrecipient_idcontentcreated_at

我想选择我发消息的最后 5 个收件人。但是,我不知道如何缩小列的范围。

我目前的查询是这样的:

SELECT DISTINCT recipient_id, created_at FROM private_messages WHERE sender_id = :user_id ORDER BY created_at DESC LIMIT 5

我无法摆脱 created_at 列,因为ORDER BY. 我一定错过了什么,但我不完全确定它是什么。

4

6 回答 6

2

....我无法摆脱 created_at 列,因为它是 ORDER BY 所必需的。

不。

Order By cluase 中的列不必出现在 SELECT 列列表中。您可以在查询的 SELECT 列表中省略created_at列。您的其余查询将正常工作。

检查显示上述事实的SQL FIDDLE 。

于 2013-06-24T04:23:44.637 回答
0

尝试: SELECT recipient_id FROM(SELECT recipient_id,MAX(created_at) as created_at FROM private_messages WHERE sender_id = :user_id GROUP BY recipient_id)a ORDER BY created_at DESC LIMIT 5;

于 2013-06-24T07:29:56.947 回答
0

尝试这个

 WITH t AS ( SELECT max(created_at) AS created_at, recipient_id  FROM messages 
 GROUP BY recipient_id  )

 SELECT created_at, recipient_id   FROM t ORDER BY created_at DESC LIMIT 5  
于 2013-06-24T08:27:44.160 回答
0

您不能省略该列。这已在一段时间前添加到 SQL 标准中。

对于 SELECT DISTINCT,ORDER BY 表达式必须出现在选择列表中

引用自 此处(来自 Tom Lane 的消息。)

实际上有一个定义上的原因。考虑

SELECT DISTINCT x FROM tab ORDER BY y;

对于表中的任何特定 x 值,可能有许多不同的 y
值。您将使用哪一个来对输出中的 x 值进行排序?

回到 SQL92,他们通过指定 ORDER BY
条目必须引用输出列来避免这个问题。SQL99 有一些乱七八糟的措辞,我认为这些措辞与我们的限制在同一个地方

例如,Oracle 不强制执行此规则(10g 或 11g)。

于 2013-06-24T07:36:19.957 回答
0

您是否尝试过类似以下的方法:

SELECT TOP 5  recipient_id
FROM private_messages 
WHERE sender_id = :user_id 
GROUP BY recipient_id
ORDER BY created_at DESC

我相信您不需要在您的选择中使用 created_at 来在 order by 子句中使用它。这可能取决于您使用的数据库系统,在 SQL Server 中它将允许这样做。

于 2013-06-24T03:46:49.233 回答
0

试试这个: SELECT DISTINCT recipient_id, created_at FROM private_messages WHERE sender_id = :user_id GROUP BY recipient_id ORDER BY created_at DESC LIMIT 5

于 2013-06-24T03:51:45.320 回答