3

私はレクリエーション数学の問題のためにMySQLで非常に大きな数までの幸運数を再現しようとしています。

ルールは基本的に、番号のリストでn番目の番号を調べ、その後のn番目ごとのインスタンスを削除することです。

最も単純な例は、自然数「2」のリストの2番目の数です。したがって、2、4、6、8などを削除します。次に、次の数字「3」を見て、3番目、6番目、9番目の用語を削除します。興味深いのは、これらの数字を数字のリストから完全に削除するため、通常の数学とは大きく異なるという事実です。「3」の次の番号は「7」です。これは、すでに4、5、および6を削除しているため、7つおきのエントリを削除することを検討しているためです。

これは本質的には数えているだけで、実際には数学ではありません。PHPとMySQLを一緒に使用すると非常にうまくいくことができます。私が直面している問題は、データベースからアレイ全体を一度に取得する必要があり、数億に達すると、通常のコンピューターではメモリ的に対応できないことです。この問題は、プログラム間でデータを転送せずに、SQLでのみ実行する必要があります。

ラッキーナンバーの詳細については、http://en.wikipedia.org/wiki/Lucky_numberが上記よりもはるかによく説明されています。

1,000,000,000(8 GB)までの奇数の整数のデータベースがあります(つまり、第2項ごとにすでに削除されています)。PHPで使用する次の番号(xと呼びます)を非常に喜んで取得できます。

SELECT * FROM table ORDER BY ID LIMIT n,1

n = 3-1,000,000,000からカウントするdo-whileループを使用します(実際には、多くの数値が削除されるため、nの上限は約150,000,000になる可能性があります)が、毎回(ループ中に)データベースに次のように要求する必要があります。各x番目の番号を削除します。

これは、別のスタックオーバーフローの質問から各x番目の番号を選択する必要があるコードです。

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

削除ステートメントになるにはこれが必要だと思いますが、本当に苦労しています。私は中程度のSQL知識しか持たないPHPプログラマーです。これを行うことにより、MySQLとPHPの間で命令を転送するだけで、大量のデータは転送しません。

ただし、誰かがMySQLでループ全体を調べてループを記述したい場合は(deleteステートメントだけでなく、それが可能かどうかもわかりません!)、それを大いに活用します。

4

1 に答える 1

4

idこのクエリの「」を使用して、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 に答える