鉴于关于允许在 dba.SE上使用基本 SQL 问题的 Meta 讨论,我提出了一个我现在遇到的问题,对此 Stack Overflow 上的答案是不充分和幼稚的。我希望有比 SO 上提出的问题更好的解决方案(因为我目前在应用程序中面临这个问题),而 dba.SE 似乎是找到更好答案的理想场所。
这是 Stack Overflow 上的原始问题:如何从 mysql 中选择每个第 n 行?
这是公认的答案:
SELECT *
FROM (
SELECT
@row := @row +1 AS rownum, [column name]
FROM (
SELECT @row :=0) r, [table name]
) ranked
WHERE rownum % [n] = 1
Run Code Online (Sandbox Code Playgroud)
接受的答案的关键问题是它需要将整个表拉到一个临时表中。因此,我已经在这个问题的标题中解决了这个问题。
还要考虑该表可能已删除行,因此仅对WHERE MOD
主键进行测试的替代查询也不是一个好的解决方案。Id est,不能相信主键是连续的。
有没有更好的方法来表达查询,该查询将返回每第二、第十或任意第 n 行,它不需要将整个表拉入内存但也考虑已删除的行?
每个第 n 行都可以定义为:
n = 2: Rows 0, 2, 4, 6, 8, ...
n = 10: Rows 0, 10, 20, 30, ...
n = 42: Rows 0, 42, 84, 126, ...
Run Code Online (Sandbox Code Playgroud)
我的目标数据库是 MySQL 5.5,运行在一个常见的 Debian 派生 Linux 发行版上。
编辑:回应托马斯的回答:
建议的解决方案没有产生预期的结果,见下文:
mysql> SELECT
-> @i:=@i+1 AS iterator
-> , t.name
-> FROM
-> events AS t,
-> (SELECT @i:=0) AS dummy
-> WHERE @i % 10 = 0
-> ORDER BY name ASC;
+----------+-------+
| iterator | name |
+----------+-------+
| 1 | 0 |
+----------+-------+
1 row in set (0.29 sec)
mysql> select count(*) from events;
+----------+
| count(*) |
+----------+
| 892507 |
+----------+
1 row in set (0.17 sec)
Run Code Online (Sandbox Code Playgroud)
对于测试数据在 events
id txtcol
-- ------
1 event0
2 event1
4 event2
5 event3
6 event4
8 event5
9 event6
Run Code Online (Sandbox Code Playgroud)
按升序检索主键值
SELECT id FROM events ORDER BY id
Run Code Online (Sandbox Code Playgroud)
将其包装在查询中以分配从零开始的排名
set @row:=-1;
SELECT @row:=@row+1 AS rownum, id
FROM
(
SELECT id FROM events ORDER BY id
) AS sorted
Run Code Online (Sandbox Code Playgroud)
将其包装在查询中以选择第一行和此后的每三行
set @row:=-1;
SELECT id
FROM
(
SELECT @row:=@row+1 AS rownum, id
FROM
(
SELECT id FROM events ORDER BY id
) AS sorted
) as ranked
WHERE rownum % 3 = 0
Run Code Online (Sandbox Code Playgroud)
最后,将其包装在查询中以检索其他列
set @row:=-1;
SELECT events.*
FROM
events
INNER JOIN
(
SELECT id
FROM
(
SELECT @row:=@row+1 AS rownum, id
FROM
(
SELECT id FROM events ORDER BY id
) AS sorted
) as ranked
WHERE rownum % 3 = 0
) AS subset
ON subset.id = events.id
Run Code Online (Sandbox Code Playgroud)
回来
id txtcol
-- ------
1 event0
5 event3
9 event6
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
19038 次 |
最近记录: |