samedi 25 mars 2017

Wrong count of values when using SUM and IF in MySQL query

I'm having a count problem in my database query when using the IF function in combination with sum.

Example database with same behavior :

CREATE TABLE `test` (
 `id` int(11) NOT NULL,
  `system` varchar(11) NOT NULL,
  `status` varchar(11) NOT NULL,
  `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Example data :

INSERT INTO `test` (`id`, `system`, `status`, `timestamp`) VALUES
(3, 'systema', 'ok', '2017-03-25 06:43:03'),
(4, 'systema', 'ok', '2017-03-25 06:43:09'),
(5, 'systema', 'fail', '2017-03-25 06:43:16'),
(6, 'systema', 'ok', '2017-03-25 06:43:22'),
(7, 'systema', 'ok', '2017-03-25 06:43:31'),
(8, 'systema', 'fail', '2017-03-25 07:12:28'),
(9, 'systema', 'fail', '2017-03-25 07:13:07'),
(10, 'systema', 'ok', '2017-03-25 07:13:13'),
(11, 'systema', 'ok', '2017-03-25 07:26:21'),
(12, 'systema', 'fail', '2017-03-25 07:26:41'),
(13, 'systema', 'fail', '2017-03-25 07:28:52'),
(14, 'systema', 'fail', '2017-03-25 07:29:13'),
(15, 'systema', 'fail', '2017-03-25 07:29:39');

Make sure all vars are empty :

mysql> set @prev_system:=null;
Query OK, 0 rows affected (0.00 sec)

mysql> set @prev_status:=null;
Query OK, 0 rows affected (0.00 sec)

mysql> set @prev_time:=null;
Query OK, 0 rows affected (0.00 sec)

Now we do the databasequery without count:

mysql> select @prev_system as old_system, @prev_status as old_status, @prev_time 
as old_time, if (@prev_status <> status and @prev_system = system and @prev_time 
< timestamp,1,NULL) as hops, @prev_system:=system as system, @prev_status:=status as 
status, @prev_time:=timestamp as timestamp from test;

The result:

+------------+------------+---------------------+------+---------+--------+---------------------+
| old_system | old_status | old_time            | hops | system  | status | timestamp           |
+------------+------------+---------------------+------+---------+--------+---------------------+
| systema    | fail       | 2017-03-25 08:29:39 | NULL | systema | ok     | 2017-03-25 07:43:03 |
| systema    | ok         | 2017-03-25 07:43:03 | NULL | systema | ok     | 2017-03-25 07:43:09 |
| systema    | ok         | 2017-03-25 07:43:09 |    1 | systema | fail   | 2017-03-25 07:43:16 |
| systema    | fail       | 2017-03-25 07:43:16 |    1 | systema | ok     | 2017-03-25 07:43:22 |
| systema    | ok         | 2017-03-25 07:43:22 | NULL | systema | ok     | 2017-03-25 07:43:31 |
| systema    | ok         | 2017-03-25 07:43:31 |    1 | systema | fail   | 2017-03-25 08:12:28 |
| systema    | fail       | 2017-03-25 08:12:28 | NULL | systema | fail   | 2017-03-25 08:13:07 |
| systema    | fail       | 2017-03-25 08:13:07 |    1 | systema | ok     | 2017-03-25 08:13:13 |
| systema    | ok         | 2017-03-25 08:13:13 | NULL | systema | ok     | 2017-03-25 08:26:21 |
| systema    | ok         | 2017-03-25 08:26:21 |    1 | systema | fail   | 2017-03-25 08:26:41 |
| systema    | fail       | 2017-03-25 08:26:41 | NULL | systema | fail   | 2017-03-25 08:28:52 |
| systema    | fail       | 2017-03-25 08:28:52 | NULL | systema | fail   | 2017-03-25 08:29:13 |
| systema    | fail       | 2017-03-25 08:29:13 | NULL | systema | fail   | 2017-03-25 08:29:39 |
+------------+------------+---------------------+------+---------+--------+---------------------+

In column 'hops' should be a '1' when status has been changed compared with old status, and 'NULL' if no change occurred, so far so good.

But when i add SUM statement to the IF statement, i do not get the expected '5' as exprected result in hops column:

Query :

mysql> select @prev_system as old_system, @prev_status as old_status, @prev_time 
as old_time, sum(if (@prev_status <> status and @prev_system = system and @prev_time < timestamp,1,NULL)) as hops, @prev_system:=system as system, 
@prev_status:=status as status, @prev_time:=timestamp as timestamp from test;

Result :

+------------+------------+----------+------+---------+--------+---------------------+
| old_system | old_status | old_time | hops | system  | status | timestamp           |
+------------+------------+----------+------+---------+--------+---------------------+
| NULL       | NULL       | NULL     |    7 | systema | ok     | 2017-03-25 07:43:03 |
+------------+------------+----------+------+---------+--------+---------------------+

I think i miss a very small thing here, who can help me out getting the sum right ?

Thanks!

Aucun commentaire:

Enregistrer un commentaire