【问题标题】:How do you select every n-th row from mysql你如何从mysql中选择每n行
【发布时间】:2009-05-13 15:49:09
【问题描述】:

我在数据库中有一系列值,我需要提取这些值来创建折线图。因为我不需要高分辨率,所以我想通过从数据库中选择每 5 行来重新采样数据。

【问题讨论】:

    标签: mysql


    【解决方案1】:

    既然你说你使用的是 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 之间的任何值,没有理由偏爱一个值而不是另一个值。

    【讨论】:

    • 我正在更新我的答案,但你打败了我!好主意。
    • 不幸的是,当处理许多条目时,这会使执行速度至少减慢 x100
    【解决方案2】:

    您可以尝试mod 5 来获取 ID 是 5 的倍数的行。(假设您有某种顺序的 ID 列。)

    select * from table where table.id mod 5 = 0;
    

    【讨论】:

    • 还假设您在序列中没有间隙,因为删除或回滚。
    • 这在大多数情况下都有效,但不考虑删除的行。
    • 简单而出色的一些测试:-​​)
    • 如果您的选择检索所有数据,这很有意义。如果您的选择中有其他标准,那么很难说它将检索到哪些数据(如果有)。
    【解决方案3】:
    SELECT * 
    FROM ( 
        SELECT 
            @row := @row +1 AS rownum, [column name] 
        FROM ( 
            SELECT @row :=0) r, [table name] 
        ) ranked 
    WHERE rownum % [n] = 1 
    

    【讨论】:

    • 有人能提供更多关于它是如何工作的信息吗?例如,每第 5 行提出一个问题,但答案中没有提到 5。
    • @Crazometer 将查询中的[n] 替换为 5 以获取每 5 行。
    • 为了扩展这一点,如果您不想从第一行开始,而是从第二行开始呢?
    • @HPWD 你会用@row :=2替换@row :=0
    • @BinarWeb 不,您可以将= 1 更改为= 2
    【解决方案4】:

    如果您使用的是 MariaDB 10.2、MySQL 8 或更高版本,则可以更高效地执行此操作,我认为使用common table expressionswindow 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 中迭代更清晰。

    【讨论】:

      【解决方案5】:
      SET @a = 0;
      SELECT * FROM t where (@a := @a + 1) % 2 = 0;
      

      【讨论】:

      • 这非常适合对任意只读表进行分区以并行处理行,并且语法非常易于阅读和理解。您只需要在主键列上添加一个 ORDER BY 以确保每行仅返回一次。
      【解决方案6】:
      SELECT *
      FROM ( 
          SELECT @row := @row +1 AS rownum, posts.*
          FROM (
              SELECT @row :=0) r, posts
          ) ranked
      WHERE rownum %3 = 1
      

      posts 是我的桌子。

      【讨论】:

        【解决方案7】:

        你可以使用这个查询,

        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 个值

        【讨论】:

          【解决方案8】:

          我一直在寻找这样的东西。 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
          

          【讨论】:

          • 谢谢,我正在找这个。我需要以某种方式检查存储过程的日志表中的某个列是否每秒钟都具有相同的值。像'proc 开始','proc 结束'。如果一切正常,下面的 sql 将返回 1。 SET @row := 0; SELECT count(distinct Message) FROM ( SELECT @row := @row +1 AS rownum, Message FROM operations.EventLog WHERE LogTime &gt; now() - interval 6 hour and ProcedureName = 'Do_CDR' ) as DT WHERE MOD(rownum,2)=0;
          【解决方案9】:

          如果您不需要结果集中的行号,您可以简化查询。

          SELECT 
              [column name] 
          FROM
              (SELECT @row:=0) temp, 
              [table name] 
          WHERE (@row:=@row + 1) % [n] = 1 
          

          替换以下占位符:

          1. [column name] 替换为您需要获取的列列表。
          2. [table name] 替换为您的表名。
          3. [n] 替换为数字。例如如果您需要每 5 行,请将其替换为 5

          【讨论】:

          • 谢谢,它很接近,但你最好这样做:select name from (SELECT @row:=-1) temp, t where (@row:=@row + 1) % 1 = 0;这有两个优点。首先,不管 n 多少,你总是得到第一行,第二行,如果你使 n = 1,你得到所有值而不是没有。 (两个变化:行中的 -1:= - 1 和 n = 0 而不是 n = 1)
          猜你喜欢
          • 2013-10-10
          • 2020-11-14
          • 2012-08-20
          • 2010-10-09
          • 2017-11-02
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多