Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MYSQL:限制每行数()_Mysql_Greatest N Per Group_Where In_Right Join_Sql Limit - Fatal编程技术网

MYSQL:限制每行数()

MYSQL:限制每行数(),mysql,greatest-n-per-group,where-in,right-join,sql-limit,Mysql,Greatest N Per Group,Where In,Right Join,Sql Limit,用户表 身份证 用户注释表 id |用户| id |内容|在创建| 我有一个用户id列表,我想为每个用户id获取最新的3条注释 SELECT * FROM user_comments WHERE user_id IN (1, 2, 3, 4, 5) ORDER BY created_at DESC LIMIT 3; 这将从所有匹配ID中获取最后3条注释,我希望每个ID的最后3条注释。首选1条不带联合的查询 我已经试着自己加入到这张桌子上,但我似乎做不好 **编辑:我不能依赖id列进行订购,它

用户表

身份证

用户注释表

id |用户| id |内容|在创建|

我有一个用户id列表,我想为每个用户id获取最新的3条注释

SELECT * FROM user_comments WHERE user_id IN (1, 2, 3, 4, 5) 
ORDER BY created_at DESC
LIMIT 3;
这将从所有匹配ID中获取最后3条注释,我希望每个ID的最后3条注释。首选1条不带联合的查询

我已经试着自己加入到这张桌子上,但我似乎做不好

**编辑:我不能依赖id列进行订购,它必须使用日期列

谢谢

**我的最终解决方案

@PaulSpiegel提出的答案确实对我有用,但我最终选择了上面的加入解决方案,我使用了来自此线程的信息:

比尔·卡温提到

谢谢大家

如果您可以使用id而不是created_at,则可以将该id与每个用户的第三高id进行比较。可以在限制为1偏移量为2的子查询中找到。对于用户少于3条注释的情况,请使用COALESCE或IFNULL选择id>=0的所有注释

如果您不能使用id进行订购

SELECT * 
FROM user_comments c
WHERE user_id IN (1, 2, 3, 4, 5)
  AND created_at >= COALESCE((
    SELECT created_at
    FROM user_comments c1
    WHERE c1.user_id = c.user_id
    ORDER BY created_at DESC
    LIMIT 1
    OFFSET 2
), '1970-01-01 00:00:00')
ORDER BY user_id, created_at DESC
请注意,如果第三条和第四条注释具有相同的时间戳,那么您可能不太可能获得超过3条注释。

如果您可以使用id而不是创建的,则可以将id与每个用户的第三个最高id进行比较。可以在限制为1偏移量为2的子查询中找到。对于用户少于3条注释的情况,请使用COALESCE或IFNULL选择id>=0的所有注释

如果您不能使用id进行订购

SELECT * 
FROM user_comments c
WHERE user_id IN (1, 2, 3, 4, 5)
  AND created_at >= COALESCE((
    SELECT created_at
    FROM user_comments c1
    WHERE c1.user_id = c.user_id
    ORDER BY created_at DESC
    LIMIT 1
    OFFSET 2
), '1970-01-01 00:00:00')
ORDER BY user_id, created_at DESC
请注意,如果第三条和第四条评论的时间戳相同,那么您可能不会收到超过3条评论。

试试看

select * 
from (
    select *, 
        @currentRank := if(@prevId = user_id, @currentRank, 0) + 1 as rank, 
        @prevId := user_id
    from user_comments
    order by user_id, created_at desc) as user_comments 
where rank <= 3
内部查询使用SQL@变量,这些变量将值从一行更改到另一行。由于按用户id排序,特定用户的注释将分组在一起。@currentRank变量将存储特定组中的行秩@新组启动时,currentRank将归零

结果是最优的,因为它只需要RDMS在user_comments表的每条记录上迭代一次。但是,外部where条款将在之后执行

试试看

select * 
from (
    select *, 
        @currentRank := if(@prevId = user_id, @currentRank, 0) + 1 as rank, 
        @prevId := user_id
    from user_comments
    order by user_id, created_at desc) as user_comments 
where rank <= 3
内部查询使用SQL@变量,这些变量将值从一行更改到另一行。由于按用户id排序,特定用户的注释将分组在一起。@currentRank变量将存储特定组中的行秩@新组启动时,currentRank将归零


结果是最优的,因为它只需要RDMS在user_comments表的每条记录上迭代一次。但是,外部where条款将在之后执行

从用户注释中选择*,其中用户id=1或用户id=2或用户id=3或用户id=4,由描述限制3处创建的订单;你有自动增量列吗?@PaulSpiegel-是的,id列是自动增量列。@BillKarwin-我能够使用该线程以正确的日期顺序运行它。谢谢从用户注释中选择*,其中用户id=1或用户id=2或用户id=3或用户id=4,由描述限制3处创建的订单;你有自动增量列吗?@PaulSpiegel-是的,id列是自动增量列。@BillKarwin-我能够使用该线程以正确的日期顺序运行它。谢谢不幸的是,我不能依赖id列来排序注释,因为在我的应用程序中,它们可以保存为草稿,并在以后发布。@magnito也可以使用时间戳-但请阅读注释。我还在子查询中添加了缺少的ORDER BY子句。我基本上能够实现这一点,但是我最终使用了BillKarwin提到的线程中提出的连接解决方案。对于重复的日期,它没有同样的问题,而且在我的情况下速度更快。不幸的是,我不能依靠id列来排序注释,因为在我的应用程序中,它们可以保存为草稿,并在以后发布。@magnito也可以使用时间戳-但请阅读注释。我还在子查询中添加了缺少的ORDER BY子句。我基本上能够实现这一点,但是我最终使用了BillKarwin提到的线程中提出的连接解决方案。它没有重复日期的问题,在我的情况下速度更快。