带有 ID 限制的 SQL SELECT

Posted

技术标签:

【中文标题】带有 ID 限制的 SQL SELECT【英文标题】:SQL SELECT with limit on ID 【发布时间】:2013-11-19 11:35:46 【问题描述】:

假设我有一个包含字段ID, Msg and time_id 的数据库表(帖子)。一个用户 (ID) 可以发布任意数量的消息。

我可以通过以下方式提取最后 15 条消息:

SELECT * FROM posts ORDER BY time_id DESC LIMIT 0,15

因为一个用户可以发布无限的消息,我需要避免显示来自一个用户的太多消息,所以我想限制一个用户最多 3 个帖子,但仍然获取 15 个。

如何获取最近 15 条最近的消息,并确保我从最近 15 条消息中可能有超过 3 条帖子的任何用户那里获得最多 3 条

【问题讨论】:

您在寻找GROUP吗? 发布您的表架构。 我认为 GROUP 在这里没有帮助,因为这会折叠每个用户的结果(消息)。您无法在数据库层应用任何逻辑来解决此问题,请在您的应用程序代码中执行。 mysql: Using LIMIT within GROUP BY to get N results per group?的可能重复 【参考方案1】:

这可能会对您有所帮助。您需要为此触发两个查询。

SELECT DISTINCT(userid) FROM `users` GROUP BY userid ORDER BY insertdate ASC LIMIt 3
 for()
SELECT msg FROM `msgtable` WHERE userid = forloopuserid ORDER BY insertdate DESC LIMIT 0,3
    //store data in a user array 
 

您的数组可能如下所示:

array(1=>array('msg1','msg2','msg3'),
2=>array('msg1','msg2','msg3')
);

【讨论】:

【参考方案2】:

您可以使用此技巧来获取每个帖子在用户中的位置

SELECT id, USER, @n:=if(USER=@last_user, @n+1, 0)  AS n , @last_user:=USER
FROM posts, (SELECT @n:=0) init
ORDER BY USER, time_id;

然后做一个 Join 或从中选择另一个并限制 n

SELECT posts.* FROM posts JOIN (
    SELECT id, USER, @n:=if(USER=@last_user, @n+1, 0)  AS n , @last_user:=USER
    FROM posts, (SELECT @n:=0) init
    ORDER BY USER, time_id) ranked USING (id)
WHERE n < 3
ORDER BY time_id
LIMIT 15

它有效(参见sqlfidle),但我不确定这是最有效的方法。如果您经常需要此请求,我建议您在单独的(去规范化的)表中运行第一个查询并在需要时更新它。

另外,如果您通过 php 运行它,SELECT @N:=0 通常在连接中不起作用。需要在之前的查询中单独完成。

【讨论】:

以上是关于带有 ID 限制的 SQL SELECT的主要内容,如果未能解决你的问题,请参考以下文章

常用sql语句

不使用带有 order 子句和更大限制 MariaDB 的索引的简单 SQL 查询

限制 SQL 查询中每个 id 的行数 [重复]

LEFT JOINed 表的 SQL 限制

带有连接和多个分组的 SQL 查询

限制 SQL JOIN