Reputation: 2428
Below is the mysql code
CREATE TABLE pricing
(
`id` INT NOT NULL AUTO_INCREMENT, `cost` FLOAT NOT NULL,
`valid_on` TIMESTAMP NOT NULL, `quantity` INT NOT NULL,
PRIMARY KEY (`id`)
);
INSERT INTO pricing (`id`, `cost`, `valid_on`, `quantity`) VALUES
(NULL, '4', '2017-01-01 00:00:00', '1'),
(NULL, '4', '2017-01-02 00:00:00', '1'),
(NULL, '4', '2017-01-03 00:00:00', '1'),
(NULL, '5', '2017-01-04 00:00:00', '2'),
(NULL, '5', '2017-01-05 00:00:00', '2'),
(NULL, '4', '2017-01-06 00:00:00', '2'),
(NULL, '4', '2017-01-07 00:00:00', '3'),
(NULL, '5', '2017-01-08 00:00:00', '3'),
(NULL, '5', '2017-01-09 00:00:00', '3'),
(NULL, '4', '2017-01-10 00:00:00', '3'),
(NULL, '4', '2017-01-11 00:00:00', '3'),
(NULL, '4', '2017-01-12 00:00:00', '2'),
(NULL, '5', '2017-01-13 00:00:00', '2'),
(NULL, '5', '2017-01-14 00:00:00', '2');
So when Group By is done on quantity following results are displayed.
select quantity, sum(cost) from pricing GROUP BY quantity
1 - 12
2 - 28
3 - 22
But actually I need something like the below results.
quantity start_date end_date cost
1 2017-01-01 00:00:00 2017-01-03 00:00:00 12
2 2017-01-04 00:00:00 2017-01-06 00:00:00 14
3 2017-01-07 00:00:00 2017-01-11 00:00:00 22
2 2017-01-12 00:00:00 2017-01-14 00:00:00 14
Can someone please help me solve this issue...
Upvotes: 1
Views: 45
Reputation: 72195
Try this:
SELECT quantity,
MIN(valid_on) AS start_date, MAX(valid_on) AS end_date,
SUM(cost)
FROM (
SELECT id, cost, valid_on, quantity,
@rn := @rn + 1 AS rn,
@grn := IF(@q = quantity, @grn + 1,
IF(@q := quantity, 1, 1)) AS grp
FROM pricing
CROSS JOIN (SELECT @rn := 0, @q := 0, @grn := 0) AS vars
ORDER BY valid_on, quantity) AS t
GROUP BY rn - grp, quantity
The query uses variables in order to identify islands of consecutive records having the same quantity
value. Using the computed grp
value, it groups separately each island and calculates start/end dates, as well as the sum of cost
.
Upvotes: 1
Reputation: 1270713
This is a pain to do in MySQL. You need to identify the groups. One method -- which is not particularly efficient -- uses a trick. For each row it counts the number of previous rows where the quantity is different from the given row. This identifies adjacent groups with the same value.
select quantity, sum(cost), min(valid_on) as start_valid_on
from (select p.*,
(select count(*)
from pricing p2
where p2.valid_on < p.valid_on and p2.quantity <> p.quantity
) as grp
from pricing p
) p
group by grp, quantity;
Upvotes: 0