假设您使用的 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 行返回一次。