【问题标题】:MySQL select records with sum greater than thresholdMySQL选择总和大于阈值的记录
【发布时间】:2015-03-19 20:14:11
【问题描述】:

我需要根据 MySQL 数据库表中列出的文件大小选择记录,使用单个查询(无存储过程)。记录集应包含总文件大小等于或如果需要超过特定阈值的所有记录。 (例如,阈值 = 30,结果返回文件大小等于 10、10、20 或 10、10、10 的 3 条记录或文件大小为 32 的 1 条记录)

表格

+----+---------+-----------+
| id | user_id | fileSize  |
+----+---------+-----------+
|  1 |       1 |      9319 |
|  2 |       1 |     51683 |
|  3 |       1 |     19776 |
|  4 |       1 |    395890 |
|  5 |       1 |      7132 |
|  6 |       1 |     97656 |
|  7 |       1 |      9798 |
|  9 |       1 |     16096 |
| 10 |       1 |    113910 |
| 11 |       1 |    160037 |
+----+---------+-----------+

在研究并尝试了许多不同的解决方案后,我想出的最佳查询如下所示:

SELECT f1.user_id, f1.id AS file_id, f1.fileSize, SUM(f2.fileSize) AS totalSum
FROM files AS f1 
INNER JOIN files AS f2 ON f1.id >= f2.id 
WHERE f1.user_id = 1
GROUP BY f1.id 
HAVING totalSum <= 350000;

示例结果

+---------+---------+-----------+----------+
| user_id | file_id |  fileSize | totalSum |
+---------+---------+-----------+----------+
|       1 |       1 |      9319 |     9319 |
|       1 |       2 |     51683 |    61002 |
|       1 |       3 |     19776 |    80778 |
+---------+---------+-----------+----------+

期望的结果

+---------+---------+-----------+----------+
| user_id | file_id |  fileSize | totalSum |
+---------+---------+-----------+----------+
|       1 |       1 |      9319 |     9319 |
|       1 |       2 |     51683 |    61002 |
|       1 |       3 |     19776 |    80778 |
|       1 |       4 |    395890 |   476668 |
+---------+---------+-----------+----------+

或者

+---------+---------+-----------+----------+
| user_id | file_id |  fileSize | totalSum |
+---------+---------+-----------+----------+
|       1 |       3 |    395890 |   395890 |
+---------+---------+-----------+----------+

上面的查询不起作用的是永远不会达到阈值,因为它基于 HAVING 小于阈值(大于仅返回远高于阈值的疯狂记录)。此外,如果集合中有任何记录的文件大小超过阈值,则查询结果有时会返回空。理想的结果会达到或略微超过阈值,并且如果单个文件大小匹配或超过阈值,则可能包含许多记录或单个记录。

任何帮助将不胜感激。我想这是我五年来第一次在网上发布问题。严重的是,被困在这个问题上一个星期。 ~ 谢了

【问题讨论】:

  • slightly exceed 无论如何,我想你在这里需要某种模糊逻辑 - 为发布的示例数据提供查询结果和预期结果
  • 好吧,我不知道该怎么表达我的意思。 “继续选择,直到总和大于或等于阈值。”会更合适。很快就会提供样本结果。
  • 我建议在您的应用程序代码中执行此操作,因为无论如何您都要检索所有行。
  • 对,但是如何在单个查询中使用 WHILE 语法?如果要使用存储过程,WHILE 肯定是首选。也许 Fox 是正确的,只需为用户选择 * 记录并在应用程序代码中过滤即可。

标签: mysql


【解决方案1】:

这似乎适合 UNION 结果集。因此,您必须获得 2 个查询(每个“标准”一个)并使用 union 连接它们的结果。

第一个查询将变为:

SELECT f1.user_id, f1.id AS file_id, SUM(f1.fileSize) AS totalSum
FROM files AS f1 
WHERE f1.user_id = 1
GROUP BY f1.id 
HAVING totalSum <= 350000;

现在您需要选择大小是否太大的查询:

SELECT f1.user_id, f1.id AS file_id, MAX(f1.fileSize) AS max
FROM files AS f1 
WHERE f1.user_id = 1
GROUP BY f1.id 
HAVING max >= 350000;

接下来,您希望将它们组合在一个查询中。由于两者具有相同的字段,您可以简单地“合并”结果

SELECT f1.user_id, f1.id AS file_id, SUM(f1.fileSize) AS totalSum
FROM files AS f1 
WHERE f1.user_id = 1
GROUP BY f1.id 
HAVING totalSum <= 350000
UNION
SELECT f1.user_id, f1.id AS file_id, MAX(f1.fileSize) AS max
FROM files AS f1 
WHERE f1.user_id = 1
GROUP BY f1.id 
HAVING max >= 350000;

PS:您将“ON f1.id >= f2.id”作为加入条件,不知道为什么 > 会非常具体:)

【讨论】:

  • 我认为某些条件可能是相反的,但您可以调整每个条件以匹配您的需要。也只是认为如果任何文件超过阈值,文件的总和也会打破该阈值,因此可能不值得检查这两个标准,除非阈值不同:)
猜你喜欢
  • 2020-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-15
  • 1970-01-01
  • 1970-01-01
  • 2011-09-25
  • 2019-06-18
相关资源
最近更新 更多