Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/60.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:将每组前N行插入表中。假设有数百万组_Mysql_Greatest N Per Group - Fatal编程技术网

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?好问题。我一定是在抽烟,这个小组实际上就是这个小组