3

我正在尝试在 MySQL 中为一个娱乐性数学问题重新创建一个非常大的幸运数字。

该规则本质上是“查看数字列表中的第 n 个数字,然后删除它之后的每个第 n 个实例。

最简单的例子是自然数列表中的第二个数字“2”。所以我们将删除 2 然后 4 然后 6 然后 8 等等。然后您将查看下一个数字“3”并删除第 3、第 6、第 9 个术语。有趣的部分来自于您将这些数字从数字列表中完全删除,因此它与普通数学非常不同。“3”之后的下一个数字是“7”,因为您已经删除了 4、5 和 6,因此您可以考虑删除每七个条目。

这本质上只是计数,而不是真正的数学——我可以在 PHP 和 MySQL 中一起做得很好。我面临的问题是,您必须一次性从数据库中获取整个数组,而当您达到数亿时,一台普通计算机就无法处理内存方面的问题。这个问题只需要在 SQL 中完成,程序之间没有数据传输。

有关 Lucky Numbers 的更多信息:http ://en.wikipedia.org/wiki/Lucky_number比我上面解释的要好得多。

我有一个高达 1,000,000,000 (8 GB) 的奇数数据库(即每第二个学期就删除一次)。我可以很高兴地在 PHP 中获得下一个要使用的数字(称为 x):

SELECT * FROM table ORDER BY ID LIMIT n,1

使用 do-while 循环从 n = 3-1,000,000,000 计数(实际上,由于删除了很多数字,n 的上限可能会变为 150,000,000 左右)但每次(在循环期间)它都需要询问数据库删除每个第 x 个数字。

这是我必须从另一个 stackoverflow 问题中选择每个第 x 个数字的代码:

SELECT * 
FROM ( 
    SELECT 
        @row := @row +1 AS rownum, [column name] 
    FROM ( 
        SELECT @row :=0) r, [table name] 
    ) ranked 
WHERE rownum % [x] = 1 

我想我只需要它成为一个删除语句,但我真的很挣扎。我是一个 PHP 程序员,只有适度的 SQL 知识。通过这样做,我只会在 MySQL 和 PHP 之间传输指令,而不是大量数据。

但是,如果有人想全力以赴并在 MySQL 中编写循环(不仅仅是 delete 语句,我什至不知道它是否可能!)那么我会充分利用它。

4

1 回答 1

4

您可以使用id此查询中的 's 删除,使用IN()条件

SELECT * FROM [table name]
-- change this to DELETE FROM [table name] when you're confident
WHERE `id` IN (
    SELECT `id`
    -- * became `id` so that we can use it in IN() above
    FROM (
        SELECT @row := @row + 1 AS 'rownum', t.`id`
        FROM (SELECT @row :=0) r, (SELECT `id` FROM [table name] ORDER BY `id`) t
        -- I made it order first because it showed an
        -- unexpected ordering for a table I tried this on
    ) ranked
    WHERE `rownum` % [n] = 0
    -- and I changed 1 into 0 because that's what we actually need
)

确保 select 语句在删除之前准确选择了您需要的内容。要检查您是否选择了正确的记录,您可以尝试以下操作。将 3 更改为您要使用的其他数字。另外,不要忘记更改[table name]为您的表的名称。

SELECT * FROM (
    SELECT @row := @row + 1 AS 'rownum', t.`id`
    FROM (SELECT @row :=0) r, (SELECT `id` FROM [table name] ORDER BY `id`) t
) ranked
WHERE `rownum` % 3 = 0
于 2013-01-10T15:46:39.683 回答