语句更改时获取有关SQL的数据

时间:2016-04-05 07:32:37

标签: mysql

我说我的数据如下。

+-------+-------+
| time  | status |
+-------+-------+
| 01:00 |  On   |
| 02:00 |  On   |
| 03:00 |  On   |
| 04:00 |  Off  |
| 05:00 |  On   |
| 06:00 |  On   |
| 07:00 |  Off  |
| 08:00 |  Off  |
| 09:00 |  On   |
| 10:00 |  On   |
| 11:00 |  Off  |
+-------+-------+

我的预期结果表是

+-------+-------+
|  On   |  Off  |
+-------+-------+
| 01:00 | 04:00 |
| 05:00 | 07:00 |
| 09:00 | 11:00 |
+-------+-------+

如何创建查询以成为我的预期结果?,因为当我无法在这种情况下使用解码时。

这是我的创建表命令

 CREATE TABLE `gps_data` (
  `id` int(255) NOT NULL AUTO_INCREMENT,
  `imei_no` int(255) DEFAULT NULL,
  `car_identification_no` varchar(255) DEFAULT NULL,
  `datetime` bigint(10) DEFAULT NULL,
  `longitude` float(10,7) DEFAULT NULL,
  `latitude` float(10,7) DEFAULT NULL,
  `engine_status` varchar(100) DEFAULT NULL,
  `speed` int(100) DEFAULT NULL,
  `mileage` bigint(255) DEFAULT NULL,
  `alarm` int(20) DEFAULT NULL,
  `address` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `car_identification_no` (`car_identification_no`)
) ENGINE=MyISAM AUTO_INCREMENT=430564 DEFAULT CHARSET=latin1

我想使用datetime和engine_status(开/关)

由于

2 个答案:

答案 0 :(得分:1)

试试这个:

SELECT MIN(CASE WHEN (grp - 1) MOD 2 + 1 = 1 THEN `time` END) AS 'On',
       MIN(CASE WHEN (grp - 1) MOD 2 + 1 = 2 THEN `time` END) AS 'Off' 
FROM (
  SELECT `time`, `status`,
         @grp := IF(@prev_status = `status`, @grp,
                    IF(@prev_status := `status`, @grp + 1, @grp + 1)) AS grp
  FROM mytable
  CROSS JOIN (SELECT @grp := 0, @prev_status = '') AS vars
  ORDER BY `time`) AS t
GROUP BY (grp - 1) DIV 2

Demo here

<强>解释

内部查询:

SELECT `time`, `status`,
      @grp := IF(@prev_status = `status`, @grp,
                 IF(@prev_status := `status`, @grp + 1, @grp + 1)) AS grp
FROM mytable
CROSS JOIN (SELECT @grp := 0, @prev_status = '') AS vars
ORDER BY `time`

使用变量来生成如下所示的派生表:

    # time,   status, grp
   ======================
    01:00:00, On,     1
    02:00:00, On,     1
    03:00:00, On,     1
    04:00:00, Off,    2
    05:00:00, On,     3
    06:00:00, On,     3
    07:00:00, Off,    4
    08:00:00, Off,    4
    09:00:00, On,     5
    10:00:00, On,     5
    11:00:00, Off,    6

因此@grp标识具有相同status值的连续记录。

外部查询分组按grp 整数除以2 。这基本上将连续的On - Off对组合在一起。最后,使用条件聚合,我们可以获得相同的SELECT OnOff值。

答案 1 :(得分:1)

SELECT t1.t "On", MIN(t2.`time`) "Off" 
FROM (
    SELECT `datetime` t, @stat := engine_status s 
    FROM gps_data JOIN (SELECT @stat='') vars 
    WHERE engine_status != @stat) t1
JOIN gps_data t2 ON t1.t < t2.`datetime`
WHERE t1.s = 'On' AND t2.engine_status = 'Off'
GROUP BY t1.t;