Следующий запрос:
SELECT * FROM
(SELECT id,
count,
@running_count := @running_count + count AS Counter
FROM sumtest, (SELECT @running_count := 0) AS T1 ORDER BY id) AS TableCount
WHERE TableCount.Counter < 50;
дает результаты:
id count Counter
1 30 30
2 10 40
3 5 45
Я скопировал вашу таблицу в MySql и назвал ее "sumtest", кстати.Пожалуйста, замените его именем таблицы.
По сути, мы вычисляем промежуточную сумму в порядке идентификатора, а затем используем ее в качестве подзапроса.
Итак, этот запрос:
SELECT id,
count,
@running_count := @running_count + count AS Counter
FROM sumtest, (SELECT @running_count := 0) AS T1
ORDER BY id
Производит:
id count Counter
1 30 30
2 10 40
3 5 45
4 20 65
5 15 80
Таким образом, становится достаточно просто выбрать все те строки, в которых счетчик меньше желаемой суммы, выполнив еще один выбор для этого.
РЕДАКТИРОВАТЬ: Здесьэто пример с курсором.Я только что скомбинировал эту функцию для вас (обратите внимание, что моя таблица называется sumtest, а моя учетная запись по умолчанию - root @ localhost):
DELIMITER $$
DROP FUNCTION IF EXISTS `Test_Cursing` $$
CREATE DEFINER=`root`@`localhost` FUNCTION `Test_Cursing`(_running_total_limit INT) RETURNS int
BEGIN
/* Why am I on StackOverflow at 01:41 on New Years Day. Dear oh dear, where's the beer? */
DECLARE _running_count INT default 0;
DECLARE _id INT;
DECLARE _current_id INT;
DECLARE _sum_count INT;
DECLARE _cur CURSOR FOR SELECT id, count FROM sumtest ORDER BY id;
OPEN _cur;
read_loop: LOOP
FETCH _cur INTO _id, _sum_count;
SET _running_count = _running_count + _sum_count;
IF _running_count > _running_total_limit THEN
LEAVE read_loop;
END IF;
SET _current_id = _id;
END LOOP;
CLOSE _cur;
RETURN _current_id;
END $$
DELIMITER ;
Вызывается так:
SELECT Test_Cursing(50);
вернет id = 3 - то есть последний идентификатор перед нарушением лимита промежуточного итога.Затем вы можете использовать это для:
SELECT * FROM sumtest WHERE id <= Test_Cursing(50);
Что возвращает:
id count
1 30
2 10
3 5