基于字段总和从表中选择随机行的快速方法

时间:2018-01-31 16:54:16

标签: mysql algorithm relational-database

我有一张包含数百餐的信息的表格。

我想快速选择特定数量的随机行,使其卡路里字段的总和等于某个数字。

考虑以下用例:

如果用户希望每天3餐中消耗1000卡路里,系统应随机返回3种不同的食物,总计1000卡路里。

我可以想到这样做的天真方式,如下所示,但我想要一种更具伸缩性的方法。

天真的做法: 从我的Python脚本,我在while循环中运行以下查询:

SELECT * FROM meal WHERE RAND()<=0.0005;

我通过计算用户提供的膳食数量0.005来计算数字3,然后将其除以表格中的总行数,例如600。这样可以确保我们从表中获得大约3行的结果。然后,我将这些行中的calorie列求和,并检查它是否等于用户指定的数量,例如1000 calories。如果它不是,我继续搜索其他行 - 我保持循环迭代,否则我退出。

1 个答案:

答案 0 :(得分:1)

考虑以下简化示例,该示例在不同程度上演示了如何提出问题以及如何回答问题:

SELECT * FROM ints;
+---+
| i |
+---+
| 0 |
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
| 7 |
| 8 |
| 9 |
+---+

SELECT i1.i meal1
     , i2.i meal2
     , i3.i meal3
     , i1.i+i2.i+i3.i 
  FROM ints i1 
  JOIN ints i2 
    ON i2.i > i1.i 
  JOIN ints i3 
    ON i3.i > i2.i 
 WHERE i1.i+i2.i+i3.i BETWEEN 18 AND 20;

+-------+-------+-------+----------------+
| meal1 | meal2 | meal3 | i1.i+i2.i+i3.i |
+-------+-------+-------+----------------+
|     1 |     8 |     9 |             18 |
|     2 |     7 |     9 |             18 |
|     2 |     8 |     9 |             19 |
|     3 |     6 |     9 |             18 |
|     3 |     7 |     8 |             18 |
|     3 |     7 |     9 |             19 |
|     3 |     8 |     9 |             20 |
|     4 |     5 |     9 |             18 |
|     4 |     6 |     8 |             18 |
|     4 |     6 |     9 |             19 |
|     4 |     7 |     8 |             19 |
|     4 |     7 |     9 |             20 |
|     5 |     6 |     7 |             18 |
|     5 |     6 |     8 |             19 |
|     5 |     6 |     9 |             20 |
|     5 |     7 |     8 |             20 |
+-------+-------+-------+----------------+