Reputation: 2041
I have 2 tables: Orders and order_line
In orders I have data like:
id | name | order_date
1 | order 1| 2014-01-01
2 | order 2| 2015-01-01
3 | order 3| 2016-01-01
In orderline there is data like:
id | Order_id | order_status |status_date
1 | 1 | New | 2014-01-01
2 | 1 | Shipped | 2014-10-01
3 | 2 | New | 2015-01-01
4 | 2 | Canceled | 2015-03-01
5 | 3 | New | 2016-01-01
6 | 3 | Canceled | 2016-02-01
a orderline does have a date and a status
Now I want to know how many lines had a Given status status in a given month/year. So for example, I would expect a value of 1 for status "New" on 2014-08, and a value of 2 for "cancelled" on 2016-03. To report that, I need to somehow get the latest order_line row for every order, and report on that. If I have just a single order, I can get the latest orderline like this:
select orderline.* from orders o
join (select * from orderline
where order_id = 1
and status_date = (select max(status_date)
from orderline
where order_id = 1
and status_date < MAKEDATE(2018, 8))) as orderline on orderline.order_id = o.id
where o.id = 1;
I would somehow need to link the sub query to the parent query I guess, but I can't figure out how to do this. When I try to replace the 1 in the sub query with "where order_id = o.id" I get Error Code: 1054. Unknown column 'o.id' in 'where clause'
code to create / fill the sample tables:
CREATE TABLE orders
(`id` int(11), `name` varchar(7), `order_date` datetime)
;
INSERT INTO orders
(`id`, `name`, `order_date`)
VALUES
(1, 'order 1', '2014-01-01 00:00:00'),
(2, 'order 2', '2015-01-01 00:00:00'),
(3, 'order 3', '2016-01-01 00:00:00')
;
CREATE TABLE orderline
(`id` int, `Order_id` int, `order_status` varchar(8), `status_date` datetime)
;
INSERT INTO orderline
(`id`, `Order_id`, `order_status`, `status_date`)
VALUES
(1, 1, 'New', '2014-01-01 00:00:00'),
(2, 1, 'Shipped', '2014-10-01 00:00:00'),
(3, 2, 'New', '2015-01-01 00:00:00'),
(4, 2, 'Canceled', '2015-03-01 00:00:00'),
(5, 3, 'New', '2016-01-01 00:00:00'),
(6, 3, 'Canceled', '2016-02-01 00:00:00')
;
Upvotes: 1
Views: 364
Reputation: 1269953
I think you want something like this:
select ol.order_status, count(*)
from orderline ol
where ol.status_date = (select max(ol2.status_date)
from orderline ol
where ol2.order_id = ol.order_id and
ol2.status_date < '2014-08-01'
)
group by ol.order_status;
This returns the number of order lines with a given status as of a particular date (the date in the subquery).
Upvotes: 2