11

所以我有点难过,我有这样的桌子设置

+-----------+------+
| Timestamp | Size |
+-----------+------+
|   1-1-13  + 10.3 +
+-----------+------+
|   1-3-13  +  6.7 +
+-----------+------+
|   1-5-13  +  3.0 +
+-----------+------+
|   1-9-13  + 11.4 +
+-----------+------+

我想知道是否有任何方法可以运行这样的查询

SELECT * FROM table ORDER BY timestamp ASC LIMIT BY (SUM(size) <= 20.0);

这应该抓取前三行,因为前 3 行的大小之和为 20。但是,它可能并不总是 3 行等于 20。有时第一行的值可能为 20,并且在那个情况下,它应该只抓住第一个。

我已经知道这可以在查询运行后快速计算 PHP 中的总和,但我正在尝试仅使用 MySQL 来完成此操作。

4

3 回答 3

7

您想添加一个运行总计,并基于此限制,以下应该有效:

SET @runtot:=0;
 SELECT 
    q1.t,
    q1.s,
    (@runtot := @runtot + q1.s) AS rt
 FROM 
    (SELECT Date AS t,
     SIZE AS s
     FROM  Table1
     ORDER  BY Date
     ) AS q1
WHERE @runtot + q1.s <= 20

编辑:这里的演示 - SQL Fiddle

于 2013-06-14T13:41:23.953 回答
6
 SELECT * FROM ints ORDER BY i;
 +---+
 | i |
 +---+
 | 0 |
 | 1 |
 | 2 |
 | 3 |
 | 4 |
 | 5 |
 | 6 |
 | 7 |
 | 8 |
 | 9 |
 +---+

 SELECT x.* ,SUM(y.i) FROM ints x JOIN ints y ON y.i <= x.i GROUP BY x.i;
 +---+----------+
 | i | SUM(y.i) |
 +---+----------+
 | 0 |        0 |
 | 1 |        1 |
 | 2 |        3 |
 | 3 |        6 |
 | 4 |       10 |
 | 5 |       15 |
 | 6 |       21 |
 | 7 |       28 |
 | 8 |       36 |
 | 9 |       45 |
 +---+----------+

 SELECT x.* ,SUM(y.i) FROM ints x JOIN ints y ON y.i <= x.i GROUP BY x.i HAVING SUM(y.i) <= 20;
 +---+----------+
 | i | SUM(y.i) |
 +---+----------+
 | 0 |        0 |
 | 1 |        1 |
 | 2 |        3 |
 | 3 |        6 |
 | 4 |       10 |
 | 5 |       15 |
 +---+----------+
于 2013-06-14T13:41:06.653 回答
0

使用窗口函数(在 MySQL 8.0+ 和 MariaDB 10.2+ 中):

SELECT *
FROM (
  SELECT t.*, SUM(size) OVER (
    PARTITION by NULL
    ORDER BY t.Timestamp
    RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
  ) as csum
  FROM MyTable t
  ORDER BY t.Timestamp
) x
WHERE csum <= 20;

或更短:

SELECT *
FROM (
  SELECT t.*, SUM(size) OVER (ORDER BY t.Timestamp) as csum
  FROM MyTable t
  ORDER BY t.Timestamp
) x
WHERE csum <= 20;

db-fiddle.com 上的演示

于 2018-06-12T19:14:41.157 回答