Say I have purchase and sales data for some SKUs:
po_id | sku | purchase_date | price | qty
----------------------------------------------
1 | 123 | 2013-01-01 12:25 | 20.15 | 5
2 | 123 | 2013-05-01 15:45 | 17.50 | 3
3 | 123 | 2013-05-02 12:00 | 15.00 | 1
4 | 456 | 2013-06-10 16:00 | 60.00 | 7
sale_id | sku | sale_date | price | qty
------------------------------------------------
1 | 123 | 2013-01-15 11:00 | 30.00 | 1
2 | 123 | 2013-01-20 14:00 | 28.00 | 3
3 | 123 | 2013-05-10 15:00 | 25.00 | 2
4 | 456 | 2013-06-11 12:00 | 80.00 | 1
How can I find the sales margin via SQL, assuming they are sold in the order they were purchased? E.g, the margin for sku 123 is
30*1 + 28*3 + 25*2 - 20.15*5 - 17.50*1
with 2 purchased at 17.50 and 1 purchased at 15.00 left unsold.
Good question. The approach that I'm taking is to calculate the total sales. Then calculate cumulative purchases, and combine them with special logic to get the right arithmetic for the combination:
select s.sku,
(MarginPos - SUM(case when s.totalqty < p.cumeqty - p.qty then p.price * p.qty
when s.totalqty between p.cumeqty - p.qty and p.qty
then s.price * (s.totalqty - (p.cumeqty - p.qty))
else 0
end)
) as Margin
from (select s.sku, SUM(price*qty) as MarginPos, SUM(qty) as totalqty
from sales s
) s left outer join
(select p.*,
(select SUM(p.qty) from purchase p2 where p2.sku = p.sku and p2.sale_id <= p.sale_id
) as cumeqty
from purchase s
)
on s.sku = p.sku
group by s.sku, MarginPos
Note: I haven't tested this query so it might have syntax errors.
setting ambient
declare #purchased table (id int,sku int,dt date,price money,qty int)
declare #sold table (id int,sku int,dt date,price money,qty int)
insert into #purchased
values( 1 , 123 , '2013-01-01 12:25' , 20.15 , 5)
,(2 , 123 , '2013-05-01 15:45' , 17.50 , 3)
,(3 , 123 , '2013-05-02 12:00' , 15.00 , 1)
,(4 , 456 , '2013-06-10 16:00' , 60.00 , 7)
insert into #sold
values(1 , 123 , '2013-01-15 11:00' , 30.00 , 1)
,(2 , 123 , '2013-01-20 14:00' , 28.00 , 3)
,(3 , 123 , '2013-05-10 15:00' , 25.00 , 2)
,(4 , 456 , '2013-06-11 12:00' , 80.00 , 1)
a sqlserver solution should be...
with cte_sold as (select sku,sum(qty) as qty, SUM(qty*price) as total_value
from #sold
group by sku
)
,cte_purchased as (select id,sku,price,qty
from #purchased
union all select id,sku,price,qty-1 as qty
from cte_purchased
where qty>1
)
,cte_purchased_ordened as(select ROW_NUMBER() over (partition by sku order by id,qty) as buy_order
,sku
,price
,1 as qty
from cte_purchased
)
select P.sku
,S.total_value - SUM(case when P.buy_order <= S.qty then P.price else 0 end) as margin
from cte_purchased_ordened P
left outer join cte_sold S
on S.sku = P.sku
group by P.sku,S.total_value,S.qty
resultset achieved
sku margin
123 45,75
456 20,00
same result for sku 123 example in the problem description...
30*1 + 28*3 + 25*2 - 20.15*5 - 17.50*1 = 45.75
This is really horrible since it changes a MySQL variable in the queries, but it kind of works (and takes 3 statements):
select
#income := sum(price*qty) as income,
#num_bought := cast(sum(qty) as unsigned) as units
from sale
where sku = 123
;
select
#expense := sum(expense) as expense,
sum(units) as units
from (select
price * least(#num_bought, qty) as expense,
least(#num_bought, qty) as units,
#num_bought := #num_bought - least(#num_bought, qty)
from purchase
where sku = 123 and #num_bought > 0
order by po_id
) as a
;
select round(#income - #expense, 2) as profit_margin;
This is Oracle query but should work in any SQL. It is simplified and does not include all necessary calculations. You can add them yourself. You will see slightly diff totals as 17.50*3 not 17.50*1:
SELECT po_sku AS sku, po_total, sale_total, (po_total-sale_total) Margin
FROM
(
SELECT SUM(price*qty) po_total, sku po_sku
FROM stack_test
GROUP BY sku
) a,
(
SELECT SUM(price*qty) sale_total, sku sale_sku
FROM stack_test_sale
GROUP BY sku
) b
WHERE po_sku = sale_sku
/
SKU PO_TOTAL SALE_TOTAL MARGIN
---------------------------------------------------
123 168.25 164 4.25
456 420 80 340
You can also add partition by SKU if required:
SUM(price*qty) OVER (PARTITION BY sku ORDER BY sku)
Related
I have a MySQL table like this;
recordID| netcall | sign | activity | netid
1 | group1 | wa1 | 1 | 20
2 | group2 | wa2 | 2 | 30
3 | group1 | wa2 | 1 | 20
4 | group2 | wa3 | 2 | 30
5 | group1 | wa1 | 1 | 40
6 | group3 | wa4 | 3 | 50
7 | group3 | wa4 | 3 | 50
8 | group1 | wa2 | 1 | 40
9 | group1 | wa1 | 1 | 40
10 | group2 | wa4 | 2 | 60
What I need from that is:
Netcall | count | activity | netid
Group1 | 3 | 1 | 40
Group2 | 2 | 2 | 30
Group3 | 2 | 3 | 50
I thought I could;
SELECT MAX(xx.mycount) AS MAXcount
FROM (SELECT COUNT(tt.sign) AS mycount ,tt.activity
FROM NetLog tt
WHERE ID <> 0
GROUP BY netcall) xx
But this only brings up the grand total not broken down by netcall. I don't see an example of this question but I'm sure there is one, I'm just asking it wrong.
Your example and desire output are too basic, you should try to expand so include more cases.
Right now you can get the desire output with:
SELECT `netcall`, COUNT(*) as `total`, MAX(`activity`) as `activity`
FROM t
GROUP BY `netcall`;
My guess is you can have different activities for group so you need multiples steps
Calculate the COUNT() for GROUP BY netcall, activity I call it q
Then see what is the MAX(total) for each netcall I call it p
Now you reuse q as o you have all the count, so just select the one with the max count.
SQL DEMO
SELECT o.`netcall`, o.total, o.`activity`
FROM (
SELECT `netcall`, COUNT(*) `total`, `activity`
FROM t
GROUP BY `netcall`, `activity`
) o
JOIN (
SELECT `netcall`, MAX(`total`) as `total`
FROM (
SELECT `netcall`, COUNT(*) `total`
FROM t
GROUP BY `netcall`, `activity`
) q
GROUP BY `netcall`
) p
ON o.`netcall` = p.`netcall`
AND o.`total` = p.`total`
With MySQL v8+ you can use cte and window function to simplify a little bit
with group_count as (
SELECT `netcall`, COUNT(*) as total, `activity`
FROM t
GROUP BY `netcall`, `activity`
), group_sort as (
SELECT `netcall`, total, `activity`,
RANK() OVER (PARTITION BY `netcall`, `activity` ORDER BY total DESC) as rnk
FROM group_count
)
SELECT *
FROM group_sort
WHERE rnk = 1
This question is asked (and answered) every day on SO; it even has its own chapter in the MySQL manual, but anyway...
SELECT a.netcall
, b.total
, a.activity
FROM netlog a
JOIN
( SELECT netcall
, MAX(record_id) record_id
, COUNT(*) total
FROM netlog
GROUP
BY netcall
) b
ON b.netcall = a.netcall
AND b.record_id = a.record_id
SELECT k.netcall, k.netID, MAX(k.logins) highest,
AVG(k.logins) average, netDate, activity
FROM
(SELECT netID, netcall, COUNT(*) logins, DATE(`logdate`) as netDate, activity
FROM NetLog
WHERE netID <> 0 AND status = 1
AND netcall <> '0' AND netcall <> ''
GROUP BY netcall, netID) k
GROUP BY netcall
ORDER BY highest DESC
Resulted in:
Net Call Highest Average Net ID Sub Net Of... ICS
214 309 Map Date Activity
MESN 65 41.5294 339 214 309 MAP 2017-09-03 MESN
W0KCN 34 14.9597 1 214 309 MAP 2016-03-15 KCNARES Weekly 2m Voice Net
W0ERH 31 31.0000 883 214 309 MAP 2018-10-12 Johnson Co. Radio Amateurs Club Meeting Net
KCABARC 29 22.3333 57 214 309 MAP 2016-10-10 KCA Blind Amateurs Weekly 2m Voice Net
....
I have a table like below
products
id price date
-------------------------------
1 1 2018-04-27 12:10:15
2 2 2018-04-27 12:10:15
3 5 2018-04-27 12:10:18
4 3 2018-04-27 12:10:18
5 4 2018-04-27 12:11:25
6 3 2018-04-27 12:11:25
Note : I have to find min price,max price, starting price,ending price of every minute.
My expected output is
firstPrice lastPrice minPrice maxPrice
---------------------------------------
1 3 1 5 --> Grouped for (2018-04-27 12:10)
4 3 3 4 --> Grouped for (2018-04-27 12:11)
My query is
SELECT b.lastPrice,c.firstPrice,min(a.price) as minPrice,max(a.price) as maxPrice from products as a left join (select price as lastPrice,date from products order by date desc) as b on a.date = b.date left join (select price as firstPrice,date from products order by date asc) as c on a.date = c.date where a.date >= '2018-04-27 12:10:00'
I don't know what to do to get the expected output.
You can use the following:
SELECT
(SELECT price FROM products WHERE DATE_FORMAT(p.`date`, '%Y%m%d%H%i') = DATE_FORMAT(`date`, '%Y%m%d%H%i') ORDER BY `date` ASC, id ASC LIMIT 1) AS firstPrice,
(SELECT price FROM products WHERE DATE_FORMAT(p.`date`, '%Y%m%d%H%i') = DATE_FORMAT(`date`, '%Y%m%d%H%i') ORDER BY `date` DESC, id DESC LIMIT 1) AS lastPrice,
MIN(price) AS minPrice, MAX(price) AS maxPrice
FROM products p
GROUP BY DATE_FORMAT(`date`, '%Y%m%d%H%i')
demo: http://sqlfiddle.com/#!9/8a989/15/0
Possibly this where first and last price are acquired in sub queries using a limit clause and grouped by date.
drop table if exists t;
create table t(id int, price int , dt datetime);
insert into t values
( 1 , 1 , '2018-04-27 12:10:15'),
( 2 , 2 , '2018-04-27 12:10:15'),
( 3 , 5 , '2018-04-27 12:10:18'),
( 4 , 3 , '2018-04-27 12:10:18'),
( 5 , 4 , '2018-04-27 12:11:25'),
( 6 , 3 , '2018-04-27 12:11:25');
select concat(date(dt),' ',hour(dt), ':',minute(dt) ,':00') Timeslot,
(select price from t t1 where concat(date(t1.dt),' ',hour(t1.dt), ':',minute(t1.dt) ,':00') = concat(date(t.dt),' ',hour(t.dt), ':',minute(t.dt) ,':00') order by id limit 1) firstprice,
(select price from t t1 where concat(date(t1.dt),' ',hour(t1.dt), ':',minute(t1.dt) ,':00') = concat(date(t.dt),' ',hour(t.dt), ':',minute(t.dt) ,':00') order by id desc limit 1) lastprice,
min(price),max(price)
from t
group by concat(date(dt),' ',hour(dt), ':',minute(dt) ,':00');
+---------------------+------------+-----------+------------+------------+
| Timeslot | firstprice | lastprice | min(price) | max(price) |
+---------------------+------------+-----------+------------+------------+
| 2018-04-27 12:10:00 | 1 | 3 | 1 | 5 |
| 2018-04-27 12:11:00 | 4 | 3 | 3 | 4 |
+---------------------+------------+-----------+------------+------------+
2 rows in set (0.00 sec)
This is my bill table:
shop_id | billing_date | total
------------------------------
ABC | 2016-03-07 | 100
ABC | 2016-03-14 | 200
DEF | 2016-03-07 | 300
DEF | 2016-03-14 | 100
GHI | 2016-03-07 | 30
I want to get one line per shop, with average total per week, the current month total, and the average total per month. This final data must look like this:
shop | weekly avg. | current month total | monthly avg.
-------------------------------------------------------
ABC | 150 | 300 | 300
DEF | 200 | 500 | 500
GHI | 30 | 30 | 30
My question is: Is it possible to get this informations directly from an SQL query?
Hey you can try this way for current year using WEEK and MONTH of mysql. as per your data entries in table is week wise:
SQLFIDDLE
select shop_id,(sum(total)/(WEEK(MAX(bdate)) - WEEK(MIN(bdate))+1)) as weekly_avg,(sum(total)/(MONTH(MAX(bdate))-MONTH(MIN(bdate))+1)) as mothly_avg, sum( case when MONTH(bdate) = MONTH(NOW()) then total else 0 end) as current_month_total from bill group by shop_id WHERE YEAR(bdate) = 2016
For number of year greater than one
SQL FIDDLE
select shop_id,
sum(total)/(12 * (YEAR(MAX(bdate)) - YEAR(MIN(bdate))) + (MONTH(MAX(bdate)) - MONTH(MIN(bdate)))+1) as month_avg,
sum(total)/(7 * (YEAR(MAX(bdate)) - YEAR(MIN(bdate))) + (WEEK(MAX(bdate)) - WEEK(MIN(bdate)))+1) as weekly_avg,
sum( case when YEAR(bdate) = YEAR(bdate) and MONTH(bdate) = MONTH(NOW()) then total else 0 end) as current_month_total from bill group by shop_id
Is this the sort of thing you are after??:
SELECT DISTINCT(bill.shop_id),wk as WeeklyTotal,mt as MonthlyTotal,ma as MonthlyAverage
FROM bill
JOIN (SELECT AVG(total) wk,shop_id
FROM bill
WHERE YEAR(billing_date) = 2016 AND MONTH(billing_date) = 1
GROUP BY shop_id) as weekly ON bill.shop_id = weekly.shop_id
JOIN (SELECT SUM(total) mt,shop_id
FROM bill
WHERE YEAR(billing_date) = 2016 AND MONTH(billing_date) = 1
GROUP BY CONCAT(shop_id,MONTH(billing_date))
) month_total ON month_total.shop_id = bill.shop_id
JOIN (SELECT AVG(total) ma,shop_id
FROM bill
WHERE YEAR(billing_date) = 2016 AND MONTH(billing_date) = 1
GROUP BY CONCAT(shop_id,MONTH(billing_date))
) month_avg ON month_avg.shop_id = bill.shop_id
You can do this using conditional aggregation and conditional logic:
select shop_id,
sum(total) / (7 * datediff(max(billing_date), min(billing_date)) + 1) as avg_weekly,
sum(case when year(billing_date) = year(now()) and month(billing_date) = month(now()) then total else 0 end) as curr_Month,
(sum(total) /
(year(max(billing_date)) * 12 + month(max(billing_date)) -
year(min(billing_date)) * 12 + month(min(billing_date))
) + 1
)
) as avg_month
total else 0 end) as week_total
from bill
gropu by shop_id;
I have a table look like below....
ID HID Date UID
1 1 2012-01-01 1002
2 1 2012-01-24 2005
3 1 2012-02-15 5152
4 2 2012-01-01 6252
5 2 2012-01-19 10356
6 3 2013-01-06 10989
7 3 2013-03-25 25001
8 3 2014-01-14 35798
How can i group by HID, Year, Month and count(UID) and add a cumulative_sum (which is count of UID). So the final result look like this...
HID Year Month Count cumulative_sum
1 2012 01 2 2
1 2012 02 1 3
2 2012 01 2 2
3 2013 01 1 1
3 2013 03 1 2
3 2014 01 1 3
What's the best way to accomplish this using query?
I made assumptions about the original data set. You should be able to adapt this to the revised dataset - although note that the solution using variables (instead of my self-join) is faster...
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
(ID INT NOT NULL
,Date DATE NOT NULL
,UID INT NOT NULL PRIMARY KEY
);
INSERT INTO my_table VALUES
(1 ,'2012-01-01', 1002),
(1 ,'2012-01-24', 2005),
(1 ,'2012-02-15', 5152),
(2 ,'2012-01-01', 6252),
(2 ,'2012-01-19', 10356),
(3 ,'2013-01-06', 10989),
(3 ,'2013-03-25', 25001),
(3 ,'2014-01-14', 35798);
SELECT a.*
, SUM(b.count) cumulative
FROM
(
SELECT x.id,YEAR(date) year,MONTH(date) month, COUNT(0) count FROM my_table x GROUP BY id,year,month
) a
JOIN
(
SELECT x.id,YEAR(date) year,MONTH(date) month, COUNT(0) count FROM my_table x GROUP BY id,year,month
) b
ON b.id = a.id AND (b.year < a.year OR (b.year = a.year AND b.month <= a.month)
)
GROUP
BY a.id, a.year,a.month;
+----+------+-------+-------+------------+
| id | year | month | count | cumulative |
+----+------+-------+-------+------------+
| 1 | 2012 | 1 | 2 | 2 |
| 1 | 2012 | 2 | 1 | 3 |
| 2 | 2012 | 1 | 2 | 2 |
| 3 | 2013 | 1 | 1 | 1 |
| 3 | 2013 | 3 | 1 | 2 |
| 3 | 2014 | 1 | 1 | 3 |
+----+------+-------+-------+------------+
If you don't mind an extra column in the result, you can simplify (and accelerate) the above, as follows:
SELECT x.*
, #running:= IF(#previous=x.id,#running,0)+x.count cumulative
, #previous:=x.id
FROM
( SELECT x.id,YEAR(date) year,MONTH(date) month, COUNT(0) count FROM my_table x GROUP BY id,year,month ) x
,( SELECT #cumulative := 0,#running:=0) vals;
The code turns out kind of messy, and it reads as follows:
SELECT
HID,
strftime('%Y', `Date`) AS Year,
strftime('%m', `Date`) AS Month,
COUNT(UID) AS Count,
(SELECT
COUNT(UID)
FROM your_db A
WHERE
A.HID=B.HID
AND
(strftime('%Y', A.`Date`) < strftime('%Y', B.`Date`)
OR
(strftime('%Y', A.`Date`) = strftime('%Y', B.`Date`)
AND
strftime('%m', A.`Date`) <= strftime('%m', B.`Date`)))) AS cumulative_count
FROM your_db B
GROUP BY HID, YEAR, MONTH
Though by using views, it should become much clearer:
CREATE VIEW temp_data AS SELECT
HID,
strftime('%Y', `Date`) as Year,
strftime('%m', `Date`) as Month,
COUNT(UID) as Count
FROM your_db GROUP BY HID, YEAR, MONTH;
Then your statement will read as follows:
SELECT
HID,
Year,
Month,
`Count`,
(SELECT SUM(`Count`)
FROM temp_data A
WHERE
A.HID = B.HID
AND
(A.Year < B.Year
OR
(A.Year = B.Year
AND
A.Month <= B.Month))) AS cumulative_sum
FROM temp_data B;
I have a two tables:
case_map
case_id | creation_date
________|___________________
49 | 2013-04-30
51 | 2013-05-15
82 | 2014-05-23
109 | 2013-06-01
123 | 2013-07-23
case_legend
id | case_id | operation_number | operation_date | failure
___|_________|__________________|________________|________
1 | 49 | 105 | 2013-05-03 | 0
2 | 51 | 105 | 2013-05-28 | 0
3 | 51 | 110 | 2013-05-29 | 0
4 | 51 | 115 | 2013-06-02 | 1
5 | 51 | 110 | 2013-06-05 | 0
6 | 82 | 105 | 2013-05-28 | 0
7 | 82 | 110 | 2013-05-30 | 0
8 | 82 | 115 | 2013-06-01 | 0
9 | 82 | 120 | 2013-06-01 | 0
10 | 82 | 125 | 2013-06-02 | 0
11 | 109 | 105 | 2013-06-27 | 0
12 | 123 | 105 | 2013-07-27 | 0
13 | 123 | 110 | 2013-08-10 | 0
And I want to know how many cases was recieved and how many of these cases are on operation 105 and 125 ('on operation' = value of operation_number for row with max operation_date for this case_id) in a certain time interval, for example 'from May, 2013 to Jule, 2013', splited by mounth.
For these purposes, I made the following query:
SELECT
`recieved_cases`.`abbreviated_date`,
`recieved_cases`.`recieved_count`,
`operation_105`.`105_count`,
`operation_125`.`125_count`
FROM (
SELECT DATE_FORMAT( `creation_date`, '%Y-%m' ) AS `abbreviated_date`, COUNT( `case_id` ) AS `recieved_count`
FROM `case_map`
WHERE `creation_date` BETWEEN '2013-05-01' AND '2013-07-31'
GROUP BY `abbreviated_date`
) AS `recieved_cases`
LEFT JOIN (
SELECT DATE_FORMAT( `t1`.`operation_date`, '%Y-%m' ) AS `abbreviated_date`, COUNT( `t1`.`operation_number` ) AS `105_count`
FROM `case_legend` AS `t1`
WHERE `t1`.`id` = (
SELECT `t2`.`id`
FROM `case_legend` AS `t2`
WHERE `t2`.`case_id` = `t1`.`case_id`
ORDER BY `t2`.`operation_date` DESC, `t2`.`id` DESC
LIMIT 1
)
AND `operation_number` = 105
GROUP BY `abbreviated_date`
) AS `operation_105`
ON `recieved_cases`.`abbreviated_date` = `operation_105`.`abbreviated_date`
LEFT JOIN (
SELECT DATE_FORMAT( `t1`.`operation_date`, '%Y-%m' ) AS `abbreviated_date`, COUNT( `t1`.`operation_number` ) AS `125_count`
FROM `case_legend` AS `t1`
WHERE `t1`.`id` = (
SELECT `t2`.`id`
FROM `case_legend` AS `t2`
WHERE `t2`.`case_id` = `t1`.`case_id`
ORDER BY `t2`.`operation_date` DESC, `t2`.`id` DESC
LIMIT 1
)
AND `operation_number` = 125
GROUP BY `abbreviated_date`
) AS `operation_125`
ON `recieved_cases`.`abbreviated_date` = `operation_125`.`abbreviated_date`
ORDER BY `recieved_cases`.`abbreviated_date`
My problem is that such a request takes into account also cases with creation_date not in a specified time interval. Ie case, which has the last operation in the specified interval, but was created earlier - is taken into account, and it should not be. How can I fix this query?
Desired result for provided example is:
abbreviated_date | recieved_count | 105_count | 125_count
_________________|________________|___________|__________
2013-05 | 2 | 0 | 0
2013-06 | 1 | 1 | 1
2013-07 | 1 | 0 | 0
Can a temporary table helps me here? I mean if I first create table like case_legend with creation_date field. I think on this one for the last hour, but not sure how to do it.
P.S. Also, if my query is bad and you can give me an advise how to optimize it - I would be grateful.
This may be what you want:
select year(cm.creation_date), month(cm.creation_date),
count(distinct case when cl.operation_number = 105 then case_id end) as op105,
count(distinct case when cl.operation_number = 125 then case_id end) as op125
from case_map cm join
case_legend cl
on cm.case_id = cl.case_id
group by year(cm.creation_date), month(cm.creation_date)
order by 1, 2;
If not, you can start with the most recent date for each of the operations:
select cm.*,
max(case when cl.operation_number = 105 then operation_date end) as op105,
max(case when cl.operation_number = 125 then operation_date end) as op125
from case_map cm join
case_legend cl
on cm.case_id = cl.case_id
group by cm.case_id;
And then work from there.
EDIT:
Now that you supplied the desired results, the query is not too difficult:
select date_format(cm.creation_date, '%Y-%m' ) as yyyymm,
sum(cl.opeartion_number = 105) as op105,
sum(cl.opeartion_number = 125) as op125
from case_map cm join
case_legend cl
on cm.case_id = cl.case_id
where not exists (select 1
from case_legend cl2
where cl2.case_id = cl.case_id and
cl2.operation_date > cl.operation_date
)
group by date_format(cm.creation_date, '%Y-%m')
order by 1;
So the answer is: You don't need temporary tables.
Here's this fiddle:
http://sqlfiddle.com/#!2/8673a3/9
It gives you the same results but in a different format perhaps, than what you prefer.
select
DATE_FORMAT( operation_date, '%Y-%m' ) as `Date`,
count(cl.case_id), cl.operation_number,
t.count
from
case_legend cl
left join case_map cm
on cl.case_id = cm.case_id
left join (
select
DATE_FORMAT( cl.operation_date, '%Y-%m' ) as `Date`, count(cl.case_id) as `count`, 'All' as operation_number
from
case_legend cl
left join case_map cm
on cl.case_id = cm.case_id
where operation_date BETWEEN '2013-05-01' AND '2013-07-31'
GROUP BY DATE_FORMAT( operation_date, '%Y-%m' )
) t
on t.Date = DATE_FORMAT( operation_date, '%Y-%m' )
where cl.operation_number in (105, 125)
and operation_date BETWEEN '2013-05-01' AND '2013-07-31'
GROUP BY DATE_FORMAT( operation_date, '%Y-%m' ), cl.operation_number
;