mysql - MySQL中自定义排序的累积和
问题描述
我有一张看起来像这样的桌子
id remaining expiry_date
1 200 2019-11-15
2 10 2019-11-23
3 10 2019-11-16
4 10 2019-11-16
5 7 2019-11-16
我想获取按顺序排序的运行总数为 215 的expiry_date
结果ascending
。
到目前为止我能做到什么?
SELECT *, @sum := (@sum + remaining) AS csum
FROM tickets
JOIN (SELECT @sum := 0) r
WHERE @sum < 215
ORDER BY id;
此查询返回以下正确的结果。
id remaining expiry_date csum
1 200 2019-11-15 200
2 10 2019-11-23 210
3 10 2019-11-16 220
但是当我尝试对其进行排序时,expiry_date
它会返回所有记录。
SELECT *, @sum := (@sum + remaining) AS csum
FROM tickets
JOIN (SELECT @sum := 0) r
WHERE @sum < 215
ORDER BY expiry_date;
结果:
id remaining expiry_date csum
1 200 2019-11-15 200
3 10 2019-11-16 210
4 10 2019-11-16 220
5 7 2019-11-16 227
2 10 2019-11-23 237
排序是正确的,但结果比我需要的要多。
我想要的是
我想返回以下结果。
id remaining expiry_date csum
1 200 2019-11-15 200
3 10 2019-11-16 210
4 10 2019-11-16 220
此外,数字215可以动态更改,因此返回的行数可以根据该数字而变化。如何更改查询以便实现此目的?
编辑
对于不清楚我在结果集中实际想要的内容,我深表歉意。请让我对此编辑进行澄清。我不希望运行总计小于给定数量的记录。我想要记录,直到运行总计等于或超过给定数量。
解决方案
首先,每个日期有多个条目。因此,仅靠日期不足以获得稳定的排序顺序。我建议ORDER BY expiry_date, id
直截了当。
然后,将使用任何现代 RDBMS 中的窗口函数进行运行总计。从版本 8 开始,它们在 MySQL 中可用。
select id, remaining, expiry_date, csum
from
(
select
id, remaining, expiry_date,
sum(remaining) over (order by expiry_date, id) as csum,
sum(remaining) over (order by expiry_date, id
rows between unbounded preceding and 1 preceding) as lag_csum
from tickets
) summed
where coalesce(lag_csum, 0) < 215
order by expiry_date, id;
如果窗口函数不可用,您可以改用相关聚合子查询。这可能要慢得多,但应该也能正常工作。
select *
from
(
select
id, remaining, expiry_date,
(
select sum(remaining)
from tickets t2
where t2.expiry_date < t1.expiry_date
or (t2.expiry_date = t1.expiry_date and t2.id <= t1.id)
) as csum,
(
select sum(remaining)
from tickets t2
where t2.expiry_date < t1.expiry_date
or (t2.expiry_date = t1.expiry_date and t2.id < t1.id)
) as lag_csum
from tickets t1
) summed
where coalesce(lag_csum, 0) < 215
order by expiry_date, id;
这两个查询都是标准 SQL,因此不限于 MySQL。
推荐阅读
- ansible - 如何创建模块 ansible 模块或插件以动态生成要推送的文件
- python - 如何用烧瓶和会话管理解决这个问题?
- javascript - 了解 javascript If else
- java - guice条件模块安装
- azure-logic-apps - 使用 Azure 逻辑应用从 FTP 位置下载文件
- c++ - 使用参数包分配具有可变参数的函数指针
- c++ - 这个递归函数中的 for 循环增量何时发生?
- javascript - 从 api 获取 giphy 并在模型视图中显示特定的 giphy
- python - 如何操作二进制文件并将结果写入另一个二进制文件
- amazon-web-services - 使用 IAM 凭证和策略 Java AWS 开发工具包将文件上传到 S3 存储桶