【发布时间】:2009-05-13 15:49:09
【问题描述】:
我在数据库中有一系列值,我需要提取这些值来创建折线图。因为我不需要高分辨率,所以我想通过从数据库中选择每 5 行来重新采样数据。
【问题讨论】:
标签: mysql
我在数据库中有一系列值,我需要提取这些值来创建折线图。因为我不需要高分辨率,所以我想通过从数据库中选择每 5 行来重新采样数据。
【问题讨论】:
标签: mysql
既然你说你使用的是 MySQL,你可以使用user variables 来创建一个连续的行编号。不过,您必须将其放在派生表(子查询)中。
SET @x := 0;
SELECT *
FROM (SELECT (@x:=@x+1) AS x, mt.* FROM mytable mt ORDER BY RAND()) t
WHERE x MOD 5 = 0;
我添加了ORDER BY RAND() 以获得伪随机抽样,而不是每次都允许无序表的每第五行出现在样本中。
匿名用户试图编辑此内容以将 x MOD 5 = 0 更改为 x MOD 5 = 1。我已经把它改回原来的了。
为了记录,在这种情况下可以使用 0 到 4 之间的任何值,没有理由偏爱一个值而不是另一个值。
【讨论】:
您可以尝试mod 5 来获取 ID 是 5 的倍数的行。(假设您有某种顺序的 ID 列。)
select * from table where table.id mod 5 = 0;
【讨论】:
SELECT *
FROM (
SELECT
@row := @row +1 AS rownum, [column name]
FROM (
SELECT @row :=0) r, [table name]
) ranked
WHERE rownum % [n] = 1
【讨论】:
[n] 替换为 5 以获取每 5 行。
@row :=2替换@row :=0
= 1 更改为= 2
如果您使用的是 MariaDB 10.2、MySQL 8 或更高版本,则可以更高效地执行此操作,我认为使用common table expressions 和window functions 更清楚。
WITH ordering AS (
SELECT ROW_NUMBER() OVER (ORDER BY name) AS n, example.*
FROM example ORDER BY name
)
SELECT * FROM ordering WHERE MOD(n, 5) = 0;
从概念上讲,这会创建一个临时表,其中包含由name 字段排序的example 表的内容,添加一个名为n 的附加字段,该字段是行号,然后仅获取那些编号为可以被 5 整除,即每 5 行。在实践中,数据库引擎通常能够更好地优化这一点。但即使它没有进一步优化它,我认为它比使用 user variables 在早期版本的 MySQL 中迭代更清晰。
【讨论】:
SET @a = 0;
SELECT * FROM t where (@a := @a + 1) % 2 = 0;
【讨论】:
SELECT *
FROM (
SELECT @row := @row +1 AS rownum, posts.*
FROM (
SELECT @row :=0) r, posts
) ranked
WHERE rownum %3 = 1
posts 是我的桌子。
【讨论】:
你可以使用这个查询,
set @n=2; <!-- nth row -->
select * from (SELECT t.*,
@rowid := @rowid + 1 AS ID
FROM TABLE t,
(SELECT @rowid := 0) dummy) A where A.ID mod @n = 0;
或者您可以将 n 替换为您的 第 n 个值
【讨论】:
我一直在寻找这样的东西。 Taylor 和 Bill 的回答让我改进了他们的想法。
table data1 有字段 read_date, value 我们想从受 read_date 范围限制的查询中选择每条二维记录 派生表的名字是任意的,这里叫DT
查询:
SET @row := 0;
SELECT * FROM ( SELECT @row := @row +1 AS rownum, read_date, value FROM data1
WHERE read_date>= 1279771200 AND read_date <= 1281844740 ) as DT WHERE MOD(rownum,2)=0
【讨论】:
SET @row := 0; SELECT count(distinct Message) FROM ( SELECT @row := @row +1 AS rownum, Message FROM operations.EventLog WHERE LogTime > now() - interval 6 hour and ProcedureName = 'Do_CDR' ) as DT WHERE MOD(rownum,2)=0;
如果您不需要结果集中的行号,您可以简化查询。
SELECT
[column name]
FROM
(SELECT @row:=0) temp,
[table name]
WHERE (@row:=@row + 1) % [n] = 1
替换以下占位符:
[column name] 替换为您需要获取的列列表。[table name] 替换为您的表名。[n] 替换为数字。例如如果您需要每 5 行,请将其替换为 5【讨论】: