MySQL:将每组前N行插入表中。假设有数百万组
为一组人这样做很简单:MySQL:将每组前N行插入表中。假设有数百万组,mysql,greatest-n-per-group,Mysql,Greatest N Per Group,为一组人这样做很简单: INSERT INTO top_dancers_by_group SELECT group_id, dancer_id FROM dancers WHERE group_id = 1 ORDER BY how_good_they_do_a_half_turn DESC LIMIT 1000 现在让我们假设有一个包含数千个组ID的groups表。如何对纯MySQL中的每个组ID执行此插入?我将使用一个存储过程: 分隔符$$ 创建过程
INSERT INTO top_dancers_by_group
SELECT group_id, dancer_id
FROM dancers
WHERE group_id = 1
ORDER BY how_good_they_do_a_half_turn DESC
LIMIT 1000
现在让我们假设有一个包含数千个组ID的groups表。如何对纯MySQL中的每个组ID执行此插入?我将使用一个存储过程: 分隔符$$ 创建过程按组插入顶级舞者 开始 声明gId int; 声明完成tinyint默认值为0; 为声明组游标 从舞者中选择不同的组id; 找不到的声明继续处理程序 设置完成=1; 开放组; 组插入:完成时=0完成 将curGroup提取到gId中; 如果完成=0,则 -如果要删除此组以前存储的舞者,请执行以下操作: 按组从顶级舞者中删除,其中组id=gId; -插入此组的顶级舞者: 按组插入顶级舞者 选择组id、舞者id 来自舞者 其中group_id=gId 按他们转了半圈的次数排序 限1000; 如果结束; 结束时; 封闭组; 结束$$ 定界符; 希望这有帮助 您还可以在此过程中使用参数定义插入的行数:
delimiter $$
create procedure insert_top_n_dancers_by_group(n int)
begin
declare gId int;
declare done tinyint default 0;
declare curGroup cursor for
select distinct group_id from dancers;
declare continue handler for not found
set done = 1;
open curGroup;
group_insert: while done=0 do
fetch curGroup into gId;
if done = 0 then
-- If you want to remove the previous stored dancers for this group:
delete from top_dancers_by_group where group_id = gId;
-- Insert the top dancers for this group:
insert into top_dancers_by_group
select group_id, dancer_id
from dancers
where group_id = gId
order by how_good_they_do_a_half_turn DESC
limit n;
end if;
end while;
close curGroup;
end $$
delimiter ;
创建过程后,可以这样调用它们:
call insert_top_dancers_by_group();
太好了,谢谢你。这里有很多MySQL的新特性,但我想我了解正在发生的一切。假设组ID是字符串,我会声明gId varchar32还是类似的东西?还有,没有切实可行的内联方法来实现这一点吗?@Dan我很高兴这对你有用。当然,gId必须与表中的group_id字段类型相同。和我认为这是最便宜的方法,特别是当你面对一张大桌子的时候。如果有用,接受它;-这最终效果非常好。从性能的角度来看,我用以下方式对其进行了修改:服务器管理top_dancers_by_group table_1和_2的两个实例,以便在更新另一个时可以读取其中一个。该过程删除现有表,创建一个不带索引的新表,插入所有行,最后添加索引。完成此过程后,服务器将更新其配置,以将新表标记为要从中读取的表。@stream which group by?好问题。我一定是在抽烟,这个小组实际上就是这个小组