サブクエリをサポートするのに十分新しいバージョンの MySQL を使用していると仮定すると、そうでない場合、MySQL 3 でまだ何をしているのでしょうか? -- 以下は、無意味な内容の一時テーブルを使用した方法の例です。
mysql> create temporary table t (n text);
Query OK, 0 rows affected (0.00 sec)
mysql> insert into t (n) values ('a'), ('b'), ('c'), ('d'), ('e');
Query OK, 5 rows affected (0.00 sec)
Records: 5 Duplicates: 0 Warnings: 0
mysql> select * from t;
+------+
| n |
+------+
| a |
| b |
| c |
| d |
| e |
+------+
mysql> SET @i = 0; SELECT i, n FROM (SELECT @i := @i + 1 AS i, n FROM t) a WHERE MOD(a.i, 2) = 0;
Query OK, 0 rows affected (0.00 sec)
+------+------+
| i | n |
+------+------+
| 2 | b |
| 4 | d |
+------+------+
2 rows in set (0.00 sec)
mysql> SET @i = 0; SELECT i, n FROM (SELECT @i := @i + 1 AS i, n FROM t) a WHERE MOD(a.i, 2) = 1;
Query OK, 0 rows affected (0.00 sec)
+------+------+
| i | n |
+------+------+
| 1 | a |
| 3 | c |
| 5 | e |
+------+------+
2 rows in set (0.00 sec)
それがどのように機能するか見てください。セッション変数 @i をゼロに設定してから、サブクエリで事前インクリメントと同等の処理を実行して、データ行とともにインデックス列を提供します。次に、外側のクエリで、@i mod 2 が 0 (偶数行の場合) または 1 (奇数行の場合) であるかどうかに基づいて行を選択しています。
説明のために外側のクエリで「i」列を選択しましたが、テクニックが機能するために同じことを行う必要はありません。もちろん、外側のクエリで * を選択している場合も同様です。 、結果の「i」列の値を無視できます。(データ テーブルに列 'i' が既にある場合は、サブクエリで別のエイリアスを使用してください。)
この手法もかなり一般化されています。WHERE MOD(ai, N) = 0 の場合、N 行ごとに返されます。