简体   繁体   中英

Mysql Finding Aggregate Between Two Other Values

I'm working with a pretty nasty table schema which unfortunately I can't change as it's defined by our SCADA program. There's one analog float value (power usage), and one digital int value (machine setting). I need to be able to find the Min, Max, and Avg of the power usage for each machine setting.

So basically each time a new machine setting (intvalue) is recorded, I need the aggregate power usage (floatvalue) until the next machine setting. I'd like to be able to group by intvalue as well, so I could get these aggregate numbers for a whole month, for example.

So far, I've tried playing around with joins and nested queries, but I can't get anything to work. I can't really find any examples like this either, since its such a poor table design.

Table schema found here: http://www.sqlfiddle.com/#!9/29164/1

Data:

    | tagid | intvalue | floatvalue |              t_stamp |
    |-------|----------|------------|----------------------|
    |     2 |        9 |     (null) | 2019-07-01T00:01:58Z |
    |     1 |   (null) |      120.2 | 2019-07-01T00:02:00Z |
    |     1 |   (null) |      120.1 | 2019-07-01T00:02:31Z |
    |     2 |       11 |     (null) | 2019-07-01T00:07:58Z |
    |     1 |   (null) |      155.9 | 2019-07-01T00:08:00Z |
    |     1 |   (null) |      175.5 | 2019-07-01T00:10:12Z |
    |     1 |   (null) |      185.5 | 2019-07-01T00:10:58Z |
    |     2 |        2 |     (null) | 2019-07-01T00:11:22Z |
    |     1 |   (null) |       10.1 | 2019-07-01T00:11:22Z |
    |     1 |   (null) |         12 | 2019-07-01T00:13:58Z |
    |     1 |   (null) |        9.9 | 2019-07-01T00:14:21Z |
    |     2 |        9 |     (null) | 2019-07-01T00:15:38Z |
    |     1 |   (null) |      120.9 | 2019-07-01T00:15:39Z |
    |     1 |   (null) |      119.2 | 2019-07-01T00:16:22Z |

Desired output:

| intvalue |   min |   avg |   max |
|----------|-------|-------|-------|
|        2 |   9.9 |  10.7 |    12 |
|        9 | 119.2 | 120.1 | 120.9 |
|       11 | 155.9 | 172.3 | 185.5 |

Is this possible?

You can fill the missing intvalues with a subquery in the SELECT clause:

select t.*, (
  select t1.intvalue
  from sqlt_data_1_2019_07 t1
  where t1.t_stamp <= t.t_stamp
    and t1.intvalue is not null
  order by t1.t_stamp desc
  limit 1
) as group_int
from sqlt_data_1_2019_07 t
order by t.t_stamp;

The result will be

| tagid | intvalue | floatvalue | t_stamp             | group_int |
| ----- | -------- | ---------- | ------------------- | --------- |
| 2     | 9        |            | 2019-07-01 00:01:58 | 9         |
| 1     |          | 120.2      | 2019-07-01 00:02:00 | 9         |
| 1     |          | 120.1      | 2019-07-01 00:02:31 | 9         |
| 2     | 11       |            | 2019-07-01 00:07:58 | 11        |
| 1     |          | 155.9      | 2019-07-01 00:08:00 | 11        |
| 1     |          | 175.5      | 2019-07-01 00:10:12 | 11        |
| 1     |          | 185.5      | 2019-07-01 00:10:58 | 11        |
| 2     | 2        |            | 2019-07-01 00:11:22 | 2         |
| 1     |          | 10.1       | 2019-07-01 00:11:22 | 2         |
| 1     |          | 12         | 2019-07-01 00:13:58 | 2         |
| 1     |          | 9.9        | 2019-07-01 00:14:21 | 2         |
| 2     | 9        |            | 2019-07-01 00:15:38 | 9         |
| 1     |          | 120.9      | 2019-07-01 00:15:39 | 9         |
| 1     |          | 119.2      | 2019-07-01 00:16:22 | 9         |

Now you can simply group by the result of the subquery:

select (
    select t1.intvalue
    from sqlt_data_1_2019_07 t1
    where t1.t_stamp <= t.t_stamp
      and t1.intvalue is not null
    order by t1.t_stamp desc
    limit 1
  ) as group_int,
  min(floatvalue) as min,
  avg(floatvalue) as avg,
  max(floatvalue) as max
from sqlt_data_1_2019_07 t
group by group_int
order by group_int;

And you get:

| group_int | min   | avg                | max   |
| --------- | ----- | ------------------ | ----- |
| 2         | 9.9   | 10.666666666666666 | 12    |
| 9         | 119.2 | 120.10000000000001 | 120.9 |
| 11        | 155.9 | 172.29999999999998 | 185.5 |

View on DB Fiddle

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM