Ищу способ выбора, пока не будет достигнута сумма.
В моей таблице «документы» есть поля «tag_id» и «size».
Я хочу выбрать все документы с помощью tag_id = 26, но знаю, что могу обрабатывать только 600 единиц размера. Итак, нет смысла выбирать 100 документов и отбрасывать 90 из них, когда я мог знать, что первые 10 уже составили> 600 единиц.
Итак, цель такова: не возвращать тонны данных для анализа, когда я собираюсь отбросить большую часть из них.
... но я бы также очень хотел избежать введения в это приложение работы с курсорами.
Я использую mysql.
Поскольку будет много комбинаций документов, добавляемых к> 600, как узнать, какие документы вы хотите использовать? Или все равно?
Предпочтение отдается недавно добавленным документам (есть поле date_created, в котором мы закажем описание)
Это похоже на работу вашей бизнес-логики / компонента / кода, которая взаимодействует с базой данных, а не на задачу самого запроса.
Мэтт ... с аналитикой это можно сделать в запросе. Если это можно сделать в базе данных, это будет быстрее.
Фильтрация записей для возврата - это именно та вещь, которую следует выполнять в базе данных, которая в значительной степени оптимизирована для данной задачи.


Вам нужен способ упорядочить, какие записи имеют приоритет над другими при добавлении к вашим максимальным единицам. В противном случае, как узнать, какой набор записей, насчитывающий в общей сложности 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
Это всего лишь базовый запрос для начала, и еще предстоит решить ряд проблем:
редактировать
Обновлено, поскольку он добавил информацию, которую он сортирует по дате.
Я начал публиковать что-то очень похожее, правда, используя вспомогательное представление. Ваш лучше.
Это тоже умнее, чем мой ответ. :)
Это намного менее эффективно, но позволяет избежать курсора (при условии, что в вашей таблице документов также есть столбец с серийным идентификатором):
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.
Затем вы можете обернуть это в другой запрос, который ищет те, у которых сумма> 600 (вам нужно будет назвать столбец суммы) и взять первый идентификатор. Затем обработайте все идентификаторы ниже, включая этот.
Эээ, если нет идентификатора, тогда используйте созданную метку времени.
Вам нужно сначала сохранить документы в табличной переменной, отсортировать их в том порядке, в котором вы хотите их получить, а затем обновить каждую строку накопительным значением, чтобы вы могли выбрать его.
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
Не знаю, стоит ли оно того.
Есть ли в MySQL аналитические функции?