I am writing a web application in PHP with MySQL.
I have a table called counts and this is how data is stored in that table:
Table: counts id counts location_id media_id created_at -------------------------------------------------- 1 50 1 1 2017-03-15 2 30 2 1 2017-03-15 3 80 1 2 2017-03-15 4 20 1 1 2017-03-16 5 100 2 2 2017-03-16
For every unique location_id, media_id and created_at, I store count.
I have another table locations which is like this:
Table: locations id name ---------------- 1 Location 1 2 Location 2 3 Location 3 4 Location 4 5 Location 5
This is the SQL Query I have at the moment:
select sum(counts.count) as views, locations.name as locations, DAYNAME(counts.created_at) AS weekday from `counts` inner join `locations` on `locations`.`id` = `counts`.`location_id` where `counts`.`created_at` between '2016-12-04' and '2016-12-10' group by `weekday`, `counts`.`location_id`;
This is how the data is displayed:
locations weekday views ----------------------------------- Location 1 Mon 50 Location 1 Tue 30 Location 2 Mon 20 Location 2 Tue 70
I'm creating reports and I would like to run a query such that all the days of the week appear as a column with their corresponding values as the view count for that day of the week. I want something like this:
locations mon tue wed thu fri sat sun ------------------------------------------------- Location 1 40 60 51 20 40 20 30 Location 2 80 60 100 24 30 10 5
Is the above possible in MySQL or I would have to use PHP to achieve that? If so, how do I go about it?
Any help will be appreciated, thanks.
NB: The sample data is not accurate.
It's possible to achieve this result with MySQL, using conditional aggregation.
The trick is to use a conditional test in an expression in the SELECT list to determine whether to return a value of count.
Something like this:
SELECT l.name AS `locations`
, SUM(IF(DATE_FORMAT(c.created_at,'%a')='Mon',c.count,0)) AS `mon`
, SUM(IF(DATE_FORMAT(c.created_at,'%a')='Tue',c.count,0)) AS `tue`
, SUM(IF(DATE_FORMAT(c.created_at,'%a')='Wed',c.count,0)) AS `wed`
, SUM(IF(DATE_FORMAT(c.created_at,'%a')='Thu',c.count,0)) AS `thu`
, SUM(IF(DATE_FORMAT(c.created_at,'%a')='Fri',c.count,0)) AS `fri`
, SUM(IF(DATE_FORMAT(c.created_at,'%a')='Sat',c.count,0)) AS `sat`
, SUM(IF(DATE_FORMAT(c.created_at,'%a')='Sun',c.count,0)) AS `sun`
FROM `locations` l
LEFT
JOIN `counts` c
ON c.location_id = l.id
AND c.created_at >= '2016-12-04'
AND c.created_at < '2016-12-04' + INTERVAL 7 DAY
GROUP BY l.name
ORDER BY l.name
NOTE:
With the sample data, there are two rows for location_id=1 and created_at='2016-03-15'
, so this query would return a total of 130 for tue
(=50+80), not 50 (as shown in the sample output of the existing query).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.