Reputation: 325
I am confused on how to query the following table. I simply want to show a count of how many was ordered and received on a specific date.
calendar table
id | date
1 | 2013-07-01
2 | 2013-07-02
3 | 2013-07-03
4 | 2013-07-04
5 | 2013-07-05
6 | 2013-07-06
7 | 2013-07-07
phone_details table
id | dateOrdered | dateReceived | upg
1 | 2013-07-01 | 2013-07-05 | exp
2 | 2013-07-02 | 2013-07-05 | post
3 | 2013-07-02 | 2013-07-06 | upgrade
4 | 2013-07-07 | 2013-07-07 | upggrade
5 | 2013-07-03 | 2013-07-04 | exp
6 | 2013-07-01 | 2013-07-02 | exp
What I would like the result to be.
calendar.date | noOrdered | noReceived | # of post | # of exp | # of upgrade
2013-07-01 | 2 | | | 2 |
2013-07-02 | 2 | 1 | 1 | | 1
2013-07-03 | 1 | | | 1 |
2013-07-04 | | 1 | | |
2013-07-05 | | 2 | | |
2013-07-06 | | 1 | | |
2013-07-07 | 1 | 1 | | 1 |
Here is my query:
select calendar.date,DAYNAME(calendar.date) as `day`,
sum(if((`phone_details`.`upg` = 'Post'),1,0)) AS `Post Paid`,
sum(if((`phone_details`.`upg` = 'Upgrade'),1,0)) AS `Upgrade`,
sum(if(((`phone_details`.`upg` = 'Exp') or (`phone_details`.`upg` = 'Future Exp')),1,0)) AS `Exp`,
(select count(phone_ID) FROM phone_details
WHERE dateReceived = calendar.date
)AS `received`
from `phone_details` JOIN calendar
where calendar.date = phone_details.dateOrdered
group by calendar.date DESC
The problem with this query is if there is nothing ordered on a date, it does not display it on the result so even if there was a receive on that date it still is not displayed. My result simply looks like the table below instead of the one above. If I subquery each column, I am able to produce the result I want but the processing time seems to slow down considerably.
calendar.date | noOrdered | noReceived | # of post | # of exp | # of upgrade
2013-07-01 | 2 | | | 2 |
2013-07-02 | 2 | 1 | 1 | | 1
2013-07-03 | 1 | | | 1 |
2013-07-07 | 1 | 1 | | 1 |
Some guidance would be appreciated. Thanks very much.
Upvotes: 1
Views: 115
Reputation: 1551
select calendar.date,DAYNAME(calendar.date) as `day`,
sum(if((`phone_details`.`upg` = 'Post'),1,0)) AS `Post Paid`,
sum(if((`phone_details`.`upg` = 'Upgrade'),1,0)) AS `Upgrade`,
sum(if(((`phone_details`.`upg` = 'Exp') or (`phone_details`.`upg` = 'Future Exp')),1,0)) AS `Exp`,
(select count(id) FROM phone_details
WHERE dateReceived = calendar.date
)AS `received`
from `phone_details` JOIN calendar
ON calendar.date = phone_details.dateOrdered or calendar.date = phone_details.dateReceived
group by calendar.date DESC
This works fine. You can check here http://sqlfiddle.com/#!2/2b9ca/3
Upvotes: -1
Reputation: 180927
You'll want a LEFT JOIN
to generate results for each row in calendar
even if they don't match anything in your phone_details
table;
SELECT c.date "calendar_date",
SUM(c.date=pd.dateOrdered) noOrdered,
SUM(c.date=pd.dateReceived) noReceived,
SUM(c.date=pd.dateOrdered AND upg='post') "# of post",
SUM(c.date=pd.dateOrdered AND upg='exp') "# of exp",
SUM(c.date=pd.dateOrdered AND upg='upgrade') "# of upgrade"
FROM calendar c
LEFT JOIN phone_details pd
ON c.date = pd.dateOrdered
OR c.date = pd.dateReceived
GROUP BY c.date;
Upvotes: 4
Reputation: 2736
I don't think your join is correct as you should use an on and not a where :
from `phone_details` JOIN calendar
where calendar.date = phone_details.dateOrdered
Try using:
from `phone_details` JOIN calendar
on calendar.date = phone_details.dateOrdered
Upvotes: 0