从 MySQL 查询中从百万行中选择第 N 条记录

Posted

技术标签:

【中文标题】从 MySQL 查询中从百万行中选择第 N 条记录【英文标题】:Select Nth record from MySQL query from Millions of rows 【发布时间】:2019-02-28 09:16:40 【问题描述】:

我有一个如下的 mysql 查询;我想在一个有 180 万条记录的表中为每个 600 条记录范围选择顶部记录。到目前为止,我必须循环 3,000 次才能完成此操作,这不是一个有效的解决方案。

数据库架构;

 Table: bet_perm_13predict
 id     bet_id      perm_id     avg_odd     avg_odd2    avg_odd3
 1      23          1           43.29       28.82       28.82
 2      23          2           42.86       28.59       28.59
 3      23          3           43.13       28.73       28.73


 Table: bet_permute_13games
 perm_id    perm_code
 1      0000000000000
 2      0000000000001
 3      0000000000002
 4      0000000000010

php 中的 MySQL 查询示例

$totRange   = 0; //Used as starting point in rang
$range      = 600; //Used as range
$stop       = 0;//Used as endPoint of range

while($totRange < 1800000)
    $stop   = $totRange+$range;

    $sql = "SELECT (tb1.avg_odd2 + tb1.avg_odd3) AS totAvg_odd ,
    tb1.perm_id , tb1.avg_odd, tb1.avg_odd2, tb1.avg_odd3, tb2.perm_code 
    FROM bet_perm_13predict tb1 
    INNER JOIN bet_permute_13games tb2 ON tb2.perm_id = tb1.perm_id
    WHERE tb1.bet_id = '$bet_id' && tb1.perm_id 
    BETWEEN $startRange AND $stop ORDER BY totAvg_odd ASC LIMIT 1"

    $q1    = $this->db->query($sql);
    $totRange = $stop;

换句话说,我想选择一个代表整个表的数据样本,该样本不是随机的,而是使用 600 范围内的顶部记录预定义的。到目前为止,我不知道如何继续。没有关于此主题的明确在线资料。

【问题讨论】:

您能否向我们展示一下表格结构、一些示例数据以及该示例数据的预期输出?您的问题没有为我们提供足够的信息。您的查询中还有一些未知变量,例如 $startRange$bet_id 向我们展示数据库架构、示例数据、当前和预期输出。请阅读How-to-Ask 这里是START 了解如何提高问题质量并获得更好答案的好地方。 How to create a Minimal, Complete, and Verifiable example 你有什么mysql版本?你有窗口函数吗? 我添加了更多信息、模式和示例数据。 MySQL 版本 5.6.21 不是每组 600 条记录,出 1.8m,让我们假设它是每组 3 条记录,共 12 条。考虑到这一点,请参阅Why should I provide an MCVE for what seems to me to be a very simple SQL query 【参考方案1】:

您可以使用整数除法来创建组。

DEMO

SELECT ID, ID DIV 600 as grp
FROM Table1

然后找到每个组的最大值。这里有一些选项

Get records with max value for each group of grouped SQL results

【讨论】:

【参考方案2】:

对于那些可能遇到同样问题的人,我就是这样解决的。我使用了@Juan Carlos 的建议并添加了一种方法来使用子查询选择组的最高记录。

SELECT * FROM 
         (SELECT * , perm_id DIV $limit as grp , (avg_odd2 + avg_odd3) AS totAvg_odd 
           FROM bet_perm_13predict WHERE bet_id = '$bet_id'  ORDER BY grp ASC ) tb1
INNER JOIN bet_permute_13games tb2 ON tb2.perm_id = tb1.perm_id
INNER JOIN bet_entry tb3 ON tb3.bet_id = tb1.bet_id
WHERE tb1.avg_odd2 < (SELECT AVG(avg_odd2) FROM bet_perm_13predict WHERE bet_id = '$bet_id' )
                     && tb1.avg_odd3 < (SELECT AVG(avg_odd3) FROM bet_perm_13predict WHERE bet_id = '$bet_id' )
GROUP BY grp ORDER BY totAvg_odd ASC
LIMIT 100

【讨论】:

以上是关于从 MySQL 查询中从百万行中选择第 N 条记录的主要内容,如果未能解决你的问题,请参考以下文章

SQL:如何从重复行中选择第一条记录?

如何在 SQL Server 中更新具有数百万行的大表?

MySQL 使用自增ID主键和UUID 作为主键的优劣比较详细过程(从百万到千万表记录测试)

MySQL 使用自增ID主键和UUID 作为主键的优劣比較具体过程(从百万到千万表记录測试)

在 HSQLDB 中选择 100+ 百万行

如何增强对数百万行表的 MySQL 查询?