mysql - 将具有相同状态的行分组,直到状态更改

标签 mysql

我有下表。对于 exery 2.5 分钟(150 秒),有两个植物的记录。我想得到一个结果,显示相应状态下工厂的最大(日期时间)和最小(日期时间)。但是对于状态的每个变化都应该有一个新行。

 plant state  unix_timest   datetime
    1   1     1452639750   2016-01-13 00:02:30
    2   1     1452639750   2016-01-13 00:02:30
    1   1     1452639900   2016-01-13 00:05:00
    2   1     1452639900   2016-01-13 00:05:00
    1   1     1452640050   2016-01-13 00:07:30
    2   1     1452640050   2016-01-13 00:07:30
    1   1     1452640200   2016-01-13 00:10:00
    2   1     1452640200   2016-01-13 00:10:00
    1   1     1452640350   2016-01-13 00:12:30
    2   0     1452640350   2016-01-13 00:12:30
    1   1     1452640500   2016-01-13 00:15:00
    2   0     1452640500   2016-01-13 00:15:00
    1   1     1452640650   2016-01-13 00:17:30
    2   1     1452640650   2016-01-13 00:17:30
    1   1     1452640800   2016-01-13 00:20:00
    2   1     1452640800   2016-01-13 00:20:00

我的 SQL 语句是:

 SELECT a.line, a.current_state, min( a.`datetime` ) AS mindate, max( a.`datetime` ) AS maxdate
    FROM `bde_production`
    LEFT JOIN bde_production a ON a.unix_timestamp = bde_production.unix_timestamp
    LEFT JOIN bde_production b ON b.unix_timestamp = bde_production.unix_timestamp -150
    GROUP BY a.line, a.current_state   ORDER BY a.line, mindate

结果:

 plant current_state    mindate              maxdate
    1   1              2016-01-13 00:02:30  2016-01-13 00:20:00
    2   1              2016-01-13 00:02:30  2016-01-13 00:20:00
    2   0              2016-01-13 00:12:30  2016-01-13 00:15:00

我希望得到的:

 plant current_state    mindate              maxdate
    1   1              2016-01-13 00:02:30  2016-01-13 00:20:00
    2   1              2016-01-13 00:02:30  2016-01-13 00:10:00
    2   0              2016-01-13 00:12:30  2016-01-13 00:15:00
    2   1              2016-01-13 00:17:30  2016-01-13 00:20:00

谢谢

最佳答案

同样,我没有得到正确的结果,但在这里留下我的划痕以防有帮助。我的基本想法是找到所有更改,为它们分配一个 ID (change_num),然后按转换分组。稍后我会编辑

CREATE TABLE bde_production (
  `id`          INT(11) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  `plant`       INT(3) UNSIGNED     NOT NULL,
  `state`       TINYINT(1) UNSIGNED NOT NULL,
  `unix_timest` INT(10) UNSIGNED    NOT NULL,
  `datetime`    DATETIME            NOT NULL
);

INSERT INTO bde_production (plant, state, unix_timest, datetime) VALUES
  (1, 1, 1452639750, "2016-01-13 00:02:30"),
  (2, 1, 1452639750, "2016-01-13 00:02:30"),
  (1, 1, 1452639900, "2016-01-13 00:05:00"),
  (2, 1, 1452639900, "2016-01-13 00:05:00"),
  (1, 1, 1452640050, "2016-01-13 00:07:30"),
  (2, 1, 1452640050, "2016-01-13 00:07:30"),
  (1, 1, 1452640200, "2016-01-13 00:10:00"),
  (2, 1, 1452640200, "2016-01-13 00:10:00"),
  (1, 1, 1452640350, "2016-01-13 00:12:30"),
  (2, 0, 1452640350, "2016-01-13 00:12:30"),
  (1, 1, 1452640500, "2016-01-13 00:15:00"),
  (2, 0, 1452640500, "2016-01-13 00:15:00"),
  (1, 1, 1452640650, "2016-01-13 00:17:30"),
  (2, 1, 1452640650, "2016-01-13 00:17:30"),
  (1, 1, 1452640800, "2016-01-13 00:20:00"),
  (2, 1, 1452640800, "2016-01-13 00:20:00");


SET @line_num_a = 0;
SET @line_num_b = 0;
SET @change_num = 0;

SELECT plant,
  IFNULL(`changes_max_state`, `bde_max_state`) AS `current_state`,
  `bde_min_date`,
  IFNULL(`changes_max_date`, `bde_max_date`),
  `changes_max_date`,
  `bde_max_date`
FROM (
       SELECT
         bde.plant,
         change_num,
         MIN(bde.datetime) `bde_min_date`,
         MAX(bde.datetime) `bde_max_date`,
         MAX(bde.state) `bde_max_state`,
         MIN(changes.datetime) `changes_min_date`,
         MAX(changes.state) `changes_max_state`,
         MAX(changes.datetime) `changes_max_date`-- MIN(bde.datetime), MAX(bde.datetime)
         , MIN(changes.datetime_b),
         MAX(changes.datetime_b)
       FROM
         bde_production bde LEFT JOIN (
                                        SELECT
                                          # a.datetime is the max reading for plant in a.state
                                          b.*, a.datetime AS datetime_b, @change_num := @change_num + 1 `change_num`
                                        FROM
                                          (
                                            SELECT
                                              *,
                                              @line_num_a := @line_num_a + 1 AS `line`
                                            FROM (
                                                   SELECT *
                                                   FROM bde_production
                                                   ORDER BY plant DESC
                                                 ) a1) a
                                          JOIN (
                                                 SELECT
                                                   *,
                                                   @line_num_b := @line_num_b + 1 AS `line`
                                                 FROM (
                                                        SELECT *
                                                        FROM bde_production
                                                        ORDER BY plant DESC
                                                      ) b1) b
                                            ON
                                              a.plant = b.plant AND a.line = b.line - 1 AND a.state <> b.state
                                      ) changes
           ON changes.plant=bde.plant AND bde.id > changes.id
       GROUP BY change_num, plant
     ) q
; 

关于mysql - 将具有相同状态的行分组,直到状态更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41693425/

相关文章:

mysql - 如何检查数据是否插入数据库

php - 分页与搜索结合的逻辑题

mysql - SQL:如何连接表并将值放入单列中

mysql - 在 talnet 软件 PuTTy 中创建表的正确语法是什么

MySQL 查询 - 如果找不到条目,​​如何返回占位符值而不是 NULL

mysql - 一行是否根据其声明的列的大小占用内存,即使字段为空?

MySQL 全文按字母/数字拆分

java - 使用preparestatement时链接到另一个应用程序

php - IMG SRC inside PHP with more PHP inside 如何

mysql - 计算不同行的日期时间差异并将它们相加以获得总计