代码之家  ›  专栏  ›  技术社区  ›  Michiel de Mare

表的及时分布

  •  10
  • Michiel de Mare  · 技术社区  · 16 年前

    我有一个mysql表,每个用户大约有3000行。其中一列是日期时间字段,它是可变的,因此行不是按时间顺序排列的。

    我想在图表中可视化时间分布,所以我需要一些单独的数据点。20个数据点就足够了。

    我可以这样做:

    select timefield from entries where uid = ? order by timefield;
    

    每150排看看。

    或者我可以做20个单独的查询并使用 limit 1 offset .

    但必须有一个更有效的解决方案…

    7 回复  |  直到 6 年前
        1
  •  5
  •   Bill Karwin    16 年前

    MichalSznajder几乎拥有它,但是在SQL的WHERE子句中不能使用列别名。所以您必须将它包装为派生表。我尝试过这个,它返回20行:

    SELECT * FROM (
        SELECT @rownum:=@rownum+1 AS rownum, e.*
        FROM (SELECT @rownum := 0) r, entries e) AS e2
    WHERE uid = ? AND rownum % 150 = 0;
    
        2
  •  1
  •   Michal Sznajder    16 年前

    我想到了这样的事

    select @rownum:=@rownum+1 rownum, entries.* 
    from (select @rownum:=0) r, entries 
    where uid = ? and rownum % 150 = 0
    

    我手头没有MySQL,但也许这会有帮助…

        3
  •  1
  •   Cade Roux    16 年前

    就可视化而言,我知道这不是你所说的周期性采样,但是我会查看用户的所有行,并选择一个间隔桶,桶内的和,显示在条形图或类似图上。这将显示一个真正的“分布”,因为在一个时间范围内的许多事件可能是重要的。

    SELECT DATEADD(day, DATEDIFF(day, 0, timefield), 0) AS bucket -- choose an appropriate granularity (days used here)
         ,COUNT(*)
    FROM entries
    WHERE uid = ?
    GROUP BY DATEADD(day, DATEDIFF(day, 0, timefield), 0)
    ORDER BY DATEADD(day, DATEDIFF(day, 0, timefield), 0)
    

    或者如果你不喜欢你必须重复自己的方式-或者如果你在玩不同的bucket,并且想在三维空间中跨多个用户进行分析(用z度量x,y uid,bucket):

    SELECT uid
        ,bucket
        ,COUNT(*) AS measure
    FROM (
        SELECT uid
            ,DATEADD(day, DATEDIFF(day, 0, timefield), 0) AS bucket
        FROM entries
    ) AS buckets
    GROUP BY uid
        ,bucket
    ORDER BY uid
        ,bucket
    

    如果我想绘制三维图,我可能会根据用户的一些有意义的总体指标来确定一种订购用户的方法。

        4
  •  0
  •   Community datashaman    7 年前

    @Michal

    无论出于什么原因,您的示例仅在where@recnum使用小于运算符时有效。我认为当WHERE过滤掉一行时,rownum不会增加,并且它不能与其他任何内容匹配。

    如果原始表有一个自动递增的ID列,并且按时间顺序插入了行,那么应该可以这样做:

    select timefield from entries
    where uid = ? and id % 150 = 0 order by timefield;
    

    当然,如果ID和时间字段之间没有关联,这就不起作用了,除非您实际上并不关心获得均匀间隔的时间字段,只有20个随机的时间字段。

        5
  •  0
  •   Scott Noyes    16 年前

    您真的关心单个数据点吗?或者,使用日数上的统计聚合函数是否足以告诉您想要知道什么?

        6
  •  0
  •   Dez    6 年前
    select timefield
    from entries
    where rand() = .01 --will return 1% of rows adjust as needed.
    

    不是MySQL专家,所以我不确定rand()在这个环境中是如何工作的。

        7
  •  0
  •   Dez    6 年前

    供我参考-对于使用postgres的用户-postgres 9.4将有顺序集聚合,可以解决这个问题:

    SELECT percentile_disc(0.95) 
    WITHIN GROUP (ORDER BY response_time) 
    FROM pageviews;
    

    来源: http://www.craigkerstiens.com/2014/02/02/Examining-PostgreSQL-9.4/