遇到一种情况,我有一个Store表的ID列表,需要从每个商店中获取最新的10个文件。
{{1}}
但是,这限制了整个结果。我找到了类似SO question的答案。但是,答案建议对每个ID使用循环。这导致多个数据库命中。
另一个选择是获取所有记录并将它们分组在代码中。但是,如果有大量记录,这将是很沉重的。
如果可以在查询级别进行处理,那就太好了。任何帮助将不胜感激。
注意::此处使用的表是虚拟表。
答案 0 :(得分:2)
MySQL 8.0之前的版本,最简单的方法可能是变量:
select f.*
from (select f.*,
(@rn := if(@s = storeId, @rn + 1,
if(@s := storeId, 1, 1)
)
) as rn
from (select f.*
from tblfiles f
where storeId in (IDs)
order by storeId, createdDate desc
) f cross join
(select @s := 0, @rn := 0) params
) f
where rn <= 10;
在MySQL 8+或MariaDB 10.3+中,您只需使用窗口函数:
select f.*
from (select f.*,
row_number() over (partition by storeid order by createdDate desc) as seqnum
from tblfiles f
) f
where seqnum <= 10;
在旧版本的MySQL和MariaDB中,可能不需要最里面的子查询。
答案 1 :(得分:1)
您可以通过UNIONed查询解决该问题,在该查询中,每个子查询都会搜索特定的ID并强制执行LIMIT子句,例如:
(SELECT *
FROM tblFiles
WHERE storeId = ?
ORDER BY createdDate DESC
LIMIT 10)
UNION
(SELECT *
FROM tblFiles
WHERE storeId = ?
ORDER BY createdDate DESC
LIMIT 10)
...
使用此解决方案,只会发生一次数据库命中的情况,并且保证您可以按每个ID获得LIMIT。这样的SQL可以很容易地从php代码中生成。
Nb:mysql查询中允许的UNION最大值为61。
答案 2 :(得分:0)
在其中使用选择
SELECT * from tblFiles where storeId in (SELECT id from store ORDER BY datefield/id field desc limit 10)