Выберите минимальное количество строк с общей суммой, большей или равной заданному порогу - PullRequest
0 голосов
/ 08 сентября 2018

У меня есть торговля таблицей sql со следующими данными

id| value | price
 1| 0.1   |1
 2| 0.5   |2
 3| 0.9   |2
 4| 0.3   |2

Как мне сделать запрос SQL, чтобы получить количество записей, ограниченное общим значением 0,9 для цены 2 по возрастанию по идентификатору. Например: -

Select Count of id FROM trade WHERE sum(value) <= 0.9 and price = '2'

Результат должен прийти как

 3

Так как всего 3 записи с идентификатором 2,3,4 со значениями 0,5,0,9,0,3 с ценой 2. Сумма их составляет 1,7, что больше 0,9, но если мы возьмем 0,5 и 0,3, оно объединится в 0,8, что меньше 0,9. Таким образом, результат должен быть равен 3, поскольку он состоит как минимум из 0,9 с ценой 2.
Также есть способ получить идентификатор результатов с последним и первым наибольшим значением в порядке.

Так это выглядит так: -

4
2
3

Помощь оценена:)

Ответы [ 3 ]

0 голосов
/ 08 сентября 2018

Этого можно добиться, используя временную переменную SQL, в которой хранятся частичные суммы и количество использованных строк. Обратите внимание, что есть два оператора SQL:

SET @tempsum := 0, @rowscount := 0;

SELECT MIN(tempcount) FROM 
  (SELECT 
      (@rowscount := @rowscount + 1) AS tempcount, 
      (@tempsum := @tempsum + value) AS tempsum 
   FROM trade WHERE 
   price='2' 
   ORDER BY value
  ) AS partialsums 
WHERE tempsum>=0.9;

Таким образом, частичные суммы строятся только один раз. Без переменных вам понадобится создать еще один подзапрос, который будет составлять несколько частичных сумм.

Здесь SQL Fiddle: http://sqlfiddle.com/#!9/38fc2/11/1

См. Также: Создание столбца накопленной суммы в MySQL


Вы также можете использовать переменные для хранения соответствующих идентификаторов, т. Е.

SET @tempsum := 0, @rowscount := 0, @ids := '';

SELECT MIN(tempcount), tempids FROM 
  (SELECT 
      (@tempsum := @tempsum + value) AS tempsum,
      (@rowscount := @rowscount + 1) AS tempcount,
      (@ids := concat(@ids, ' ', id)) AS tempids
   FROM trade WHERE 
   price='2' 
   ORDER BY value
  ) AS partialsums 
WHERE tempsum>=0.9;

См. Скрипку: http://sqlfiddle.com/#!9/38fc2/33/0

0 голосов
/ 11 сентября 2018
select id from 
    (select id, if(not(@sum > 0.9), 1, 0) mark,  (@sum:=@sum+value) as sum 
        from trade cross join  (select @sum:=0) s  
        where price=2 order by value asc) t 
where mark =1 

Внутренний запрос подсчитывает совокупную сумму и дополнительное поле mark, которое равно one, когда сумма меньше, и превращается в ноль, когда оно превышает 0,9. Так как он работает на один шаг позже, он собирает первый ряд, где сумма превышает предел.

Результат внутреннего выбора

id   mark   sum
4    1      0.30000001192092896
2    1      0.800000011920929
3    1      1.699999988079071

Теперь во внешнем запросе вам просто нужно выбрать строки с mark, равным 1. И это приводит к 4,2,3

демо на sqlfiddle

0 голосов
/ 08 сентября 2018

Если вам нужен счетчик значений различных идентификаторов, вы можете использовать счетчик (отличный идентификатор)

и выполнять тот факт, что вы проверяете агрегированный результат (сумма () ..), который вы должны использовать, имея, а негде

Select Count(distinct id ) 

FROM trade 
where price = 2
HAVING sum(value) <= 0.9 

если вы хотите, чтобы количество строк с идентификатором отличалось от нуля, то вы можете использовать счетчик (id)

Select Count(id ) 
FROM trade 
 where price = 2
HAVING sum(value) <= 0.9 

Обратите внимание, что вы используете цену в качестве строки

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...