表格的及时分配

时间:2020-03-05 18:38:05  来源:igfitidea点击:

我有一个MySQL表,每个用户约有3000行。列之一是日期时间字段,该字段是可变的,因此这些行不是按时间顺序排列的。

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

我可以这样做:

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

并查看第150行。

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

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

解决方案

回答

我想到了这样的事情

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

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

回答

@米哈尔

无论出于何种原因,示例仅在where @recnum使用小于运算符时有效。我认为,当where过滤掉一行时,rownum不会递增,并且无法匹配其他任何内容。

如果原始表具有自动递增的id列,并且按时间顺序插入了行,则此方法应该起作用:

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

如果id与时间字段之间没有相关性,那当然是行不通的,除非我们实际上并不关心获得均匀间隔的时间字段(只有20个随机时间字段)。

回答

我们真的关心单个数据点吗?还是在日数上使用统计汇总函数足以告诉我们我们想知道什么?

  • AVG
  • STDDEV_POP
  • 方差
  • TO_DAYS

回答

select timefield
from entries
where rand() = .01 --will return 1% of rows adjust as needed.

不是mysql专家,所以我不确定rand()在这种环境下如何运行。

回答

Michal Sznajder几乎拥有它,但是我们不能在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;

回答

就可视化而言,我知道这不是我们要讨论的定期采样,但是我会查看用户的所有行,然后选择一个间隔存储桶,这些存储桶中的SUM并显示在条形图或者类似图形上。这将显示出真正的"分布",因为在某个时间范围内发生的许多事件可能都是重要的。

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)

或者,如果我们不喜欢必须重复的方式,或者我们正在使用不同的存储桶,并且想要在多个3D用户中进行分析(针对X,YUID,存储桶的Z值):

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

如果我想以3-D绘图,则可能会确定一种根据对用户有意义的总体指标对用户进行排序的方法。