题
我正在寻找一种选择方法,直到达到总和。
我的“文档”表有“tag_id
“ 和 ”size
”字段。
我想选择所有文档 tag_id = 26
但我知道我只能处理 600 个单位的尺寸。因此,当我知道前 10 个文档加起来已经超过 600 个单位时,选择 100 个文档并丢弃其中 90 个是没有意义的。
所以,目标是:当我要丢弃大部分数据时,不要带回大量数据进行解析。
...但我也很想避免在这个应用程序中引入光标的使用。
我正在使用mysql。
解决方案
当总计达到最大单位时,您需要某种方法来排序哪些记录优先于其他记录。否则,你怎么知道你保留了哪一组总计达 600 条的记录呢?
SELECT d.id, d.size, d.date_created
FROM documents d
INNER JOIN documents d2 ON d2.tag_id=d.tag_id AND d2.date_created >= d.date_created
WHERE d.tag_id=26
GROUP BY d.id, d.size, d.date_created
HAVING sum(d2.size) <= 600
ORDER BY d.date_created DESC
这只是一个帮助您入门的基本查询,还有许多问题需要解决:
- 它停止于 <= 600,因此在大多数情况下您不会完全填满大小限制。这意味着您可能需要对其进行调整以允许多一条记录。例如,如果第一条记录 > 600,则查询将不返回任何内容,这可能是一个问题。
- 稍后它不会做任何事情来检查可能仍然符合上限的其他较小记录。
- 具有相同 date_created 值的记录有时可能会被“重复计算”。
编辑
自从他添加了按日期排序的信息后进行了更新。
其他提示
效率低得多,但它确实避免了游标(假设你的文档表也有一个序列id列):
select a.id, (select sum(b.size) from documents b where b.id <= a.id and b.tag_id = 26)
from documents a
where a.tag_id = 26
order by a.id
另外,这是在pgsql中完成的,所以我不确定这个确切的语法是否适用于mysql。
然后你可以将它包装在另一个查找具有&gt;的查询中。 600(你必须命名sum列)并取第一个id。然后处理下面的所有ID,包括那个。
您必须首先将文档存储在表变量中,按照要检索它们的顺序对它们进行排序,然后使用累积值更新每一行,以便您可以选择它。
declare @documents_temp table (
tag_id int,
size int,
cumulative_size int null)
insert into @documents_temp
select tag_id, size, size from documents order by tag_id
update @documents_temp d set d.cumulative_size = d.size +
(select top 1 cumulative_size from @documents_temp
where tag_id < d.tag_id order by tag_id desc)
select tag_id, size from @documents_temp where cumulative_size <= 600
不知道是否值得。
不隶属于 StackOverflow