Reputation: 45
I have a sales table with the following columns:
mysql> select * from sales;
+-------------+--------+------------+
| customer_id | amount | date |
+-------------+--------+------------+
| 1 | 12 | 2015-01-01 |
| 1 | 1 | 2015-01-02 |
| 1 | 663 | 2015-02-12 |
| 2 | 22 | 2015-01-03 |
| 2 | 21 | 2015-02-12 |
| 2 | 11 | 2015-02-12 |
| 2 | 9 | 2015-04-12 |
+-------------+--------+------------+
And I can get near to what I want using this query:
SELECT
customer_id,
sum(if(month(date) = 1, amount, 0)) AS Jan,
sum(if(month(date) = 2, amount, 0)) AS Feb,
sum(if(month(date) = 3, amount, 0)) AS Mar,
sum(if(month(date) = 4, amount, 0)) AS Apr,
sum(if(month(date) = 5, amount, 0)) AS May,
sum(if(month(date) = 6, amount, 0)) AS Jun,
sum(if(month(date) = 7, amount, 0)) AS Jul,
sum(if(month(date) = 8, amount, 0)) AS Aug,
sum(if(month(date) = 9, amount, 0)) AS Sep,
sum(if(month(date) = 10, amount, 0)) AS Oct,
sum(if(month(date) = 11, amount, 0)) AS Nov,
sum(if(month(date) = 12, amount, 0)) AS `Dec`
FROM sales
GROUP BY customer_id;
The output format required:
+-------------+------+------+------+------+------+------+------+------+------+------+------+------+
| customer_id | Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec |
+-------------+------+------+------+------+------+------+------+------+------+------+------+------+
| 1 | 13 | 663 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 2 | 22 | 32 | 0 | 9 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
+-------------+------+------+------+------+------+------+------+------+------+------+------+------+
However I'd like the average per month, when I change sum to avg, I dont get the average.
SELECT
customer_id,
avg(if(month(date) = 1, amount, 0)) AS Jan,
avg(if(month(date) = 2, amount, 0)) AS Feb,
avg(if(month(date) = 3, amount, 0)) AS Mar,
avg(if(month(date) = 4, amount, 0)) AS Apr,
avg(if(month(date) = 5, amount, 0)) AS May,
avg(if(month(date) = 6, amount, 0)) AS Jun,
avg(if(month(date) = 7, amount, 0)) AS Jul,
avg(if(month(date) = 8, amount, 0)) AS Aug,
avg(if(month(date) = 9, amount, 0)) AS Sep,
avg(if(month(date) = 10, amount, 0)) AS Oct,
avg(if(month(date) = 11, amount, 0)) AS Nov,
avg(if(month(date) = 12, amount, 0)) AS `Dec`
FROM sales
GROUP BY customer_id;
Output (which isnt avg per month):
+-------------+--------+----------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+
| customer_id | Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec |
+-------------+--------+----------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+
| 1 | 4.3333 | 221.0000 | 0.0000 | 0.0000 | 0.0000 | 0.0000 | 0.0000 | 0.0000 | 0.0000 | 0.0000 | 0.0000 | 0.0000 |
| 2 | 5.5000 | 8.0000 | 0.0000 | 2.2500 | 0.0000 | 0.0000 | 0.0000 | 0.0000 | 0.0000 | 0.0000 | 0.0000 | 0.0000 |
+-------------+--------+----------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+
I'm going a bit mad trying to figure out whats happening, any one offer some advice? Thanks
CREATE TABLE `sales` (
`customer_id` int(11) NOT NULL,
`amount` int(11) DEFAULT NULL,
`date` date DEFAULT NULL
)
INSERT INTO `sales` VALUES (1,12,'2015-01-01'),(1,1,'2015-01-02'),(1,663,'2015-02-12'),(2,22,'2015-01-03'),(2,21,'2015-02-12'),(2,11,'2015-02-12'),(2,9,'2015-04-12');
Upvotes: 1
Views: 1691
Reputation: 3202
A quick workaround is :
SELECT
customer_id,
MAX(if(`month` = 1, amount, 0)) AS Jan,
MAX(if(`month` = 2, amount, 0)) AS Feb,
MAX(if(`month` = 3, amount, 0)) AS Mar,
MAX(if(`month` = 4, amount, 0)) AS Apr,
MAX(if(`month` = 5, amount, 0)) AS May,
MAX(if(`month` = 6, amount, 0)) AS Jun,
MAX(if(`month` = 7, amount, 0)) AS Jul,
MAX(if(`month` = 8, amount, 0)) AS Aug,
MAX(if(`month` = 9, amount, 0)) AS Sep,
MAX(if(`month` = 10, amount, 0)) AS Oct,
MAX(if(`month` = 11, amount, 0)) AS Nov,
MAX(if(`month` = 12, amount, 0)) AS `Dec`
FROM
(
SELECT
customer_id,
(month(date)) `month`,
AVG(amount) amount
FROM sales
GROUP BY customer_id,(month(date))
) AS T
GROUP BY customer_id;
Upvotes: 0
Reputation: 64
SELECT
customer_id,
SUM(Jan) AS Jun,
SUM(Feb) AS Feb,
SUM(Mar) AS Mar,
SUM(Apr) AS Apr,
SUM(May) AS May,
SUM(Jun) AS Jun,
SUM(Jul) AS Jul,
SUM(Aug) AS Aug,
SUM(Sep) AS Sep,
SUM(Oct) AS Oct,
SUM(Nov) AS Nov,
SUM(`Dec`) AS `Dec`
FROM (
SELECT
customer_id,
avg(if(month(date) = 1, amount, 0)) AS Jan,
avg(if(month(date) = 2, amount, 0)) AS Feb,
avg(if(month(date) = 3, amount, 0)) AS Mar,
avg(if(month(date) = 4, amount, 0)) AS Apr,
avg(if(month(date) = 5, amount, 0)) AS May,
avg(if(month(date) = 6, amount, 0)) AS Jun,
avg(if(month(date) = 7, amount, 0)) AS Jul,
avg(if(month(date) = 8, amount, 0)) AS Aug,
avg(if(month(date) = 9, amount, 0)) AS Sep,
avg(if(month(date) = 10, amount, 0)) AS Oct,
avg(if(month(date) = 11, amount, 0)) AS Nov,
avg(if(month(date) = 12, amount, 0)) AS `Dec`
FROM sales
GROUP BY customer_id, month(date)
) AS a GROUP BY customer_id
Upvotes: 0
Reputation: 1270573
The problem are the 0
s. The do not affect the sum()
, but they do affect the average. You can change them to NULL
:
SELECT customer_id,
avg(if(month(date) = 1, amount, NULL)) AS Jan,
avg(if(month(date) = 2, amount, NULL)) AS Feb,
avg(if(month(date) = 3, amount, NULL)) AS Mar,
avg(if(month(date) = 4, amount, NULL)) AS Apr,
avg(if(month(date) = 5, amount, NULL)) AS May,
avg(if(month(date) = 6, amount, NULL)) AS Jun,
avg(if(month(date) = 7, amount, NULL)) AS Jul,
avg(if(month(date) = 8, amount, NULL)) AS Aug,
avg(if(month(date) = 9, amount, NULL)) AS Sep,
avg(if(month(date) = 10, amount, NULL)) AS Oct,
avg(if(month(date) = 11, amount, NULL)) AS Nov,
avg(if(month(date) = 12, amount, NULL)) AS `Dec`
FROM sales
GROUP BY customer_id;
As a note: I prefer case
because it is ANSI standard, so I would write this as:
avg(case when month(date) = 1 then amount end) as Jan,
Upvotes: 2
Reputation: 125
Try something like this:
SELECT
customer_id,
if(month(hlp_tab2.date) = 1, hlp_tab2.amount, 0) AS Jan,
if(month(hlp_tab2.date) = 2, hlp_tab2.amount, 0) AS Feb,
if(month(hlp_tab2.date) = 3, hlp_tab2.amount, 0) AS Mar,
if(month(hlp_tab2.date) = 4, hlp_tab2.amount, 0) AS Apr,
if(month(hlp_tab2.date) = 5, hlp_tab2.amount, 0) AS May,
if(month(hlp_tab2.date) = 6, hlp_tab2.amount, 0) AS Jun,
if(month(hlp_tab2.date) = 7, hlp_tab2.amount, 0) AS Jul,
if(month(hlp_tab2.date) = 8, hlp_tab2.amount, 0) AS Aug,
if(month(hlp_tab2.date) = 9, hlp_tab2.amount, 0) AS Sep,
if(month(hlp_tab2.date) = 10, hlp_tab2.amount, 0) AS Oct,
if(month(hlp_tab2.date) = 11, hlp_tab2.amount, 0) AS Nov,
if(month(hlp_tab2.date) = 12, hlp_tab2.amount, 0) AS `Dec`
FROM (
SELECT
hlp_tab.customer_id,
avg(hlp_tab.amount) 'amount',
hlp_tab.date
FROM (
SELECT
customer_id,
amount,
month(date) 'date'
FROM sales
) hlp_tab
group by
hlp_tab.customer_id,
hlp_tab.date
) hlp_tab2
Upvotes: 0