I have an Intranet site that only registered users can watch videos. Users can watch videos on several platforms like iPhone, iPad, Android or Web and I track all those information (for the simplicity of the problem, please do not consider other platforms). I am trying to display some video watch reports at admin panel.
Table structure is below (I have lots of other columns but they are not important for this problem);
CREATE TABLE IF NOT EXISTS `history` (
`history_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`video_id` int(11) unsigned NOT NULL,
`user_id` int(11) unsigned NOT NULL,
`platform_id` int(11) unsigned NOT NULL,
`created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`history_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=9 ;
INSERT INTO `history` (`history_id`, `video_id`, `user_id`, `platform_id`, `created`) VALUES
(1, 1, 1, 1, '2012-05-06 08:13:57'),
(2, 2, 1, 1, '2012-05-06 13:23:57'),
(3, 1, 1, 4, '2012-05-06 18:16:39'),
(4, 4, 2, 3, '2012-05-07 08:14:19'),
(5, 1, 2, 3, '2012-05-07 08:14:55'),
(6, 2, 1, 1, '2012-05-07 15:14:55'),
(7, 3, 2, 1, '2012-05-07 18:05:14'),
(8, 3, 1, 4, '2012-05-07 18:15:24');
CREATE TABLE IF NOT EXISTS `sys_list_of_values` (
`value_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`display_text` text COLLATE utf8_unicode_ci NOT NULL,
`list_value` text COLLATE utf8_unicode_ci NOT NULL,
`list_group` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`value_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=10 ;
INSERT INTO `sys_list_of_values` (`value_id`, `display_text`, `list_value`, `list_group`) VALUES
(1, 'iPhone', 'iphone', 'platform'),
(2, 'Android', 'android', 'platform'),
(3, 'iPad', 'ipad', 'platform'),
(4, 'Website', 'web', 'platform'),
(5, 'Active', 'active', 'status'),
(6, 'Passive', 'passive', 'status'),
(7, 'Waiting for approvement', 'waiting', 'status'),
(8, 'Spam', 'spam', 'status'),
(9, 'Deleted', 'deleted', 'status');
CREATE TABLE IF NOT EXISTS `users` (
`user_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(80) COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`user_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=3 ;
INSERT INTO `users` (`user_id`, `username`) VALUES
(1, 'test_user_1'),
(2, 'test_user_2');
CREATE TABLE IF NOT EXISTS `videos` (
`video_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`user_id` int(11) unsigned NOT NULL,
`title` varchar(200) COLLATE utf8_unicode_ci NOT NULL,
`created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`status` int(11) unsigned NOT NULL,
PRIMARY KEY (`video_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=5 ;
INSERT INTO `videos` (`video_id`, `user_id`, `title`, `created`, `status`) VALUES
(1, 1, 'Test Video 1', '2012-05-07 08:12:52', 7),
(2, 1, 'Test Video 2', '2012-05-07 08:12:52', 5),
(3, 1, 'Test Video 3', '2012-05-07 08:13:17', 5),
(4, 1, 'Test Video 4', '2012-05-07 08:13:17', 6);
I am trying to display a report like below;
Platform | Watch_Count
===============================
iPhone 20
iPad 0
Android 2
Website 120
Total 142
I have some filter options, like video_id, created, platform etc. For example; I want to display a total watch report for all videos, or for a specific video (video_id), or between dates (created) etc. I also want to display all platforms, whether they are 0 or anything.
The following query displays only iPhone and Website, but I want to display all platforms. If there are no watch count, then it has to be displayed as 0 (zero). I also can’t display a final row which sums all watch_counts and displays a total.
SELECT sys_list_of_values.display_text, COUNT(history.history_id) AS 'total_watch' FROM history
JOIN sys_list_of_values ON sys_list_of_values.value_id = history.platform_id
WHERE history.video_id = 1
AND history.created < '2012-05-07'
GROUP BY history.platform_id
Retaining your
FROM HISTORY, change yourJOINtoRIGHT JOINIf you want to use
LEFT JOIN, switch the places of history and sys_list_of_values:Live test: http://www.sqlfiddle.com/#!2/495d1/15
GROUP BY with ROLLUP is incompatible with ORDER, anyway ROLLUP automatically sorts the list, just remove the ORDER:
Live test: http://www.sqlfiddle.com/#!2/495d1/68