mySchema:
create table Warehouse
(
ware_id int,
weight int unsigned,
added_date date
);
insert into Warehouse
values (56, 21, '2008-04-04'),
(42, 40, '2009-10-13'),
(10, 11, '2010-11-14'),
(22, 2, '2010-11-22'),
(19, 27, '2012-01-25'),
(80, 14, '2012-01-25'),
(21, 31, '2012-03-11'),
(52, 32, '2012-05-30'),
(49, 4, '2013-02-26'),
(77, 17, '2013-05-24'),
(22, 54, '2016-04-18'),
(40, 19, '2017-02-20');
I have a warehouse that stores many wares in it with restriction in weights.
The sum of all wares must less than or equal to 272.
If a new ware wants to be added and warehouse capacity is full, we must remove the oldest wares in order to make free space for the new one, and this process will be continued until warehouse free-space is equal or greater than new ware weight.
How can I do a simple query to return all of the wares that need to be removed?
For example, if the weight of the new item is 100, the query should return something like this:
| ware_id | weight | added_date |
|---------|--------|------------|
| 56 | 21 | 2008-04-04 |
| 42 | 40 | 2009-10-13 |
| 10 | 11 | 2010-11-14 |
| 22 | 2 | 2010-11-22 |
| 19 | 27 | 2012-01-25 |
If you are running MySQL 8.0, you can do a window sum:
select *
from (
select
w.*,
sum(weight) over(order by added_date desc, ware_id) running_weight
from Warehouse w
) t
where running_weight > 272
order by added_date desc, ware_id;
The inner query computes a running sum of the weight
s, starting with the most recent record, and by descending added_date
(we use ware_id
to break the ties). The outer query pulls out all the records for which the running sum exceeds 272.
Your initial dataset has a total weight of 272.
Let's add a recent record with a weight of 100.
insert into Warehouse values (99, 100, '2019-11-23');
Now the query returns:
ware_id | weight | added_date | running_weight ------: | -----: | :--------- | -------------: 19 | 27 | 2012-01-25 | 284 80 | 14 | 2012-01-25 | 298 22 | 2 | 2010-11-22 | 300 10 | 11 | 2010-11-14 | 311 42 | 40 | 2009-10-13 | 351 56 | 21 | 2008-04-04 | 372
If you are running in MySQL 5.6 you can do this:
SET @sum = 0;
SELECT ware_id, weight, added_date
FROM (
SELECT
ware_id,
weight,
added_date,
(@sum:=@sum + weight) AS sum_weights
FROM
Warehouse
ORDER BY added_date DESC
) as sumed_weights
WHERE sumed_weights.sum_weights > (272 - 100)
Where 100 is the weight of the new item.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.