すべての結果をテーブルに表示するクエリを作成したいと考えていますが、テーブルの先頭から 5 オフセットされています。私の知る限り、MySQL にLIMIT
は制限とオフセットが必要です。これを行う方法はありますか?
10 に答える
特定のオフセットから結果セットの最後までのすべての行を取得するには、2番目のパラメーターに大きな数値を使用できます。このステートメントは、96行目から最後の行までのすべての行を取得します。
SELECT * FROM tbl LIMIT 95, 18446744073709551615;
おっしゃるように、LIMITが必要なので、可能な限り最大の制限である18446744073709551615(符号なしBIGINTの最大値)を使用する必要があります。
SELECT * FROM somewhere LIMIT 18446744073709551610 OFFSET 5
他の回答で述べたように、MySQL は制限内のレコード数として 18446744073709551615 を使用することを提案していますが、これを考慮してください。実際、1,000,000,000 レコードを取得したらどうしますか?
10 億を超えるレコードが必要な場合もありますが、私のポイントは、必要な数には制限があり、18 京未満であるということです。安定性、最適化、および場合によっては使いやすさのために、クエリに意味のある制限を設定することをお勧めします。これにより、魔法のように見える数字を見たことがない人の混乱も軽減され、一度に処理できるレコードの数を少なくとも伝えられるという追加の利点もあります。
データベースから 18 京のレコードをすべて取得する必要がある場合、おそらく本当に必要なのは、それらを 1 億単位で取得し、1840 億回ループすることです。
もう 1 つの方法は、自動インクリメントされた列を選択し、HAVING を使用してフィルター処理することです。
SET @a := 0;
select @a:=@a + 1 AS counter, table.* FROM table
HAVING counter > 4
しかし、私はおそらく上限アプローチに固執するでしょう.
他の人が述べたように、MySQL マニュアルから。これを実現するために、unsigned big int の最大値、つまりこのひどい数値 (18446744073709551615) を使用できます。しかし、チルダ「~」ビットごとの演算子を使用すると、もう少し面倒になりません。
LIMIT 95, ~0
これはビットごとの否定として機能します。「~0」の結果は 18446744073709551615 です。
LIMIT で MySQL ステートメントを使用できます。
START TRANSACTION;
SET @my_offset = 5;
SET @rows = (SELECT COUNT(*) FROM my_table);
PREPARE statement FROM 'SELECT * FROM my_table LIMIT ? OFFSET ?';
EXECUTE statement USING @rows, @my_offset;
COMMIT;
MySQL 5.5.44 でテスト済み。したがって、番号 18446744073709551615 の挿入を回避できます。
注: トランザクションは、変数 @rows がステートメントの実行で考慮されるテーブルと一致していることを確認します。
LC#1321を実践しているときに、すべての日付を選択する必要があるのに最初の 6 つの日付がスキップされるという非常によく似た問題に遭遇しました。
ROW_NUMBER()
ウィンドウ関数とサブクエリを使用して、MySQL でこれを実現しました。たとえば、次のクエリは、最初の 5 行をスキップしてすべての結果を返します。
SELECT
fieldname1,
fieldname2
FROM(
SELECT
*,
ROW_NUMBER() OVER() row_num
FROM
mytable
) tmp
WHERE
row_num > 5;
特に必要に応じて、サブクエリにさらにロジックを追加する必要がある場合がありOVER()
ます。さらに、実際のオフセット ロジックに依存する代わりに、 RANK()
/DENSE_RANK()
ウィンドウ関数を使用することもできます。ROW_NUMBER()
参照:
ちょうど今日、私はmysqlテーブルから大量のデータ(100万行以上)を取得するための最良の方法について読んでいました。1つの方法は、提案されているように、オフセットと返される最後の行がLIMIT x,y
どこにあるかを使用することです。しかし、私が知ったように、それはそうするための最も効率的な方法ではありません。自動インクリメント列がある場合は、どのレコードから開始するかを示す句を含むステートメントを簡単に使用できます。x
y
SELECT
WHERE
例えば、
SELECT * FROM table_name WHERE id > x;
mysqlは、使用するとすべての結果を取得LIMIT
し、オフセットに収まるレコードのみを表示するようです。パフォーマンスには最適ではありません。
出典:この質問への回答MySQLフォーラム。注意してください、質問は約6歳です。
WHERE .... AND id > <YOUROFFSET>
id は、自動インクリメントまたは一意の数値列にすることができます...