Suppose the following schema
CREATE TABLE `log_apache` (
`date` datetime NOT NULL,
`count` int(10) unsigned NOT NULL,
`input` bigint(20) unsigned NOT NULL,
`output` bigint(20) unsigned NOT NULL,
`server` char(30) NOT NULL,
`vhostid` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`date`,`server`,`vhostid`),
UNIQUE KEY `date` (`date`,`vhostid`,`input`,`output`)
);
INSERT INTO log_apache VALUES ('2014-04-01', 12, 19031, 1358358, 'server 1', 11);
INSERT INTO log_apache VALUES ('2014-04-01', 1, 41051, 151977, 'server 1', 15);
INSERT INTO log_apache VALUES ('2014-04-01', 22, 4051, 11115, 'server 1', 5);
INSERT INTO log_apache VALUES ('2014-04-01', 21, 5893, 81906, 'server 2', 5);
INSERT INTO log_apache VALUES ('2014-04-01', 13, 4051, 11115, 'server 5', 11);
INSERT INTO log_apache VALUES ('2014-04-02', 9, 8195, 331551, 'server 3', 115);
INSERT INTO log_apache VALUES ('2014-04-02', 12, 19031, 1358358, 'server 2', 12);
INSERT INTO log_apache VALUES ('2014-04-02', 12, 19031, 1358358, 'server 3', 2);
INSERT INTO log_apache VALUES ('2014-04-03', 12, 19031, 1358358, 'server 4', 11);
INSERT INTO log_apache VALUES ('2014-04-01', 12, 19031, 1358358, 'server 4', 51);
INSERT INTO log_apache VALUES ('2014-04-02', 12, 19031, 1358358, 'server 1', 11);
I need to form a view of the table that looks more like this
-----------------------------------------------------------------------------------
| Server | 2014-04-01 | 2014-04-02 |
----------------------------------------------------------------------------------|
| Server 1 | sum(`count`*input) | sum(`count`*output) | input calc | output calc |
| Server 2 | sum(`count`*input) | sum(`count`*output) | input calc | output calc |
| Server 3 | sum(`count`*input) | sum(`count`*output) | input calc | output calc |
| Server 4 | sum(`count`*input) | sum(`count`*output) | input calc | output calc |
| Server 5 | sum(`count`*input) | sum(`count`*output) | input calc | output calc |
-----------------------------------------------------------------------------------
But not just with one day but for every day.
Ideally I'd have a where condition for the view so I could isolate vhostid and date range. I believe this requires a pivot table but I have very little experience with them and am not sure how to begin constructing such a query. If you could help with this and provide and explanation as to how and why the query should be that way that would be fantastic.
PS I came up with this query but clearly the result set it wrong.
SELECT t0.server, t1.`date_in`, t1.`date_out`, t2.`date_in`, t2.`date_out`
FROM (select distinct(server) as server from log_apache order by server) as t0
LEFT JOIN (SELECT server as Server,
sum(`count`*input) as date_in,
sum(`count`*output) as date_out
FROM log_apache
WHERE vhostid = 11
AND `date` = '2014-04-01'
GROUP BY server) as t1
ON t0.server = t1.server
LEFT JOIN (SELECT server as server,
sum(`count`*input) as date_in,
sum(`count`*output) as date_out
FROM log_apache
WHERE vhostid = 11
AND `date` = '2014-04-02'
GROUP BY server) as t2
ON t0.server = t2.server
Best Answer
May be you need much more simple table?
That table can be produced by:
Some suggestions about efficiency:
Replace
server char(30) NOT NULL
withserver_id INT NOT NULL
. Grouping by INT way more faster than by CHAR() as far as no collation conversions needed.Create separate index
(date, server_id)
forGROUP BY
.Precalculate
count*input
on insertion to spread the load.