代码之家  ›  专栏  ›  技术社区  ›  Barry Chapman

从一组MySQL记录中选择一组分布式样本记录

  •  0
  • Barry Chapman  · 技术社区  · 6 年前

    我真的希望能够选择(比如)10条记录,它们在指定的时间段内以某种程度上均匀的分布出现。

    ID       DEVICE_ID       LA         LO          CREATED         
    -------------------------------------------------------------------
    1           1           23.4        948.7       2018-12-13 00:00:01
    2           2           22.4        948.2       2018-12-13 00:01:01
    3           2           28.4        948.3       2018-12-13 00:02:22
    4           1           26.4        948.6       2018-12-13 00:02:33
    5           1           21.4        948.1       2018-12-13 00:02:42
    6           1           22.4        948.3       2018-12-13 00:03:02
    7           1           28.4        948.0       2018-12-13 00:03:11
    8           2           23.4        948.8       2018-12-13 00:03:12
    ...                                                             
    492         2           21.4        948.4       2018-12-13 00:03:25
    493         1           22.4        948.2       2018-12-13 00:04:01
    494         1           24.4        948.7       2018-12-13 00:04:02
    495         2           27.4        948.1       2018-12-13 00:05:04
    

    考虑到这个数据集,我不想提取所有这些行,而是希望每隔50条记录从集合中提取一行(返回的大约500行中有10行)。

    这可能吗?如果需要的话,我可以在我的应用程序代码中这样做,但我想看看MySQL中是否有一个函数或什么东西可以处理这个问题。

    这是我尝试过的查询,目前可以使用-但我希望结果分布更均匀,而不是按RAND()分布。

    SELECT * FROM (
    SELECT * FROM (
    SELECT t.*, DATE_SUB(NOW(), INTERVAL 30 HOUR) as offsetdate
    
    from tracking t
    HAVING created > offsetdate) as parp
    ORDER BY RAND()
    LIMIT 10) as mastr
    ORDER BY id ASC;
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   fifonik    6 年前

    不要按RAND()排序,因为它是为每一行计算的RAND,然后重新排序,只有这样您才能选择一些记录。

    您可以尝试以下方法:

    SELECT
        *
    FROM
        (
            SELECT
                tracking.*
                , @rownum := @rownum + 1 AS rownum
            FROM
                tracking
                , (SELECT @rownum := 0) AS dummy
            WHERE
                created > DATE_SUB(NOW(), INTERVAL 30 HOUR)
        ) AS s
    WHERE
        (rownum % 10) = 0
    

    此外,您可能会考虑使用类似“和(UNIXYTIMESTATED(创建)%60=0”)之类的东西,这与您想要的略有不同,但可能是(取决于您的插入分布)。