MySQL 查询能量计数器的差值/差值和缺失值插值

问题描述 投票:0回答:1

我每 15 分钟在 MySQL 数据库中记录一次电能计数器 (kWh)。 有时,记录会因多种原因而失败(断电、计算机重新启动以进行更新......)并且值丢失。

表格如下:

id      Time                Energy
27800   13.02.2024 23:30:01 651720048
27801   13.02.2024 23:45:00 651720672
(missing)
27802   14.02.2024 00:15:02 651721917
27803   14.02.2024 00:30:00 651722540
27804   14.02.2024 00:45:00 651723129
27805   14.02.2024 01:00:02 651723769
27806   14.02.2024 01:15:01 651724405
27807   14.02.2024 01:30:01 651725030
(missing)
27808   14.02.2024 02:00:01 651726275
27809   14.02.2024 02:15:02 651726880
27810   14.02.2024 02:30:01 651727519
27811   14.02.2024 02:45:00 651728130
27812   14.02.2024 03:00:02 651728751
27813   14.02.2024 03:15:02 651729381

我正在寻找一个 MySQL 查询,它返回特定(可变)时间跨度(例如 15 分钟、60 分钟、24 小时、1 个月...)内的消耗(能量计数器值之间的差值/差异),该查询还考虑了通过插值法缺失值。

结果应如列

Consumption 15m
Consumption 1h
:

中所示
id      Time                Energy      Consumption 15m     Consumption 1h
27800   13.02.2024 23:30:01 651720048   -   
27801   13.02.2024 23:45:00 651720672   624 
(missing)                   651721294.5 622.5               -
27802   14.02.2024 00:15:02 651721917   622.5   
27803   14.02.2024 00:30:00 651722540   623 
27804   14.02.2024 00:45:00 651723129   589 
27805   14.02.2024 01:00:02 651723769   640                 2474,5
27806   14.02.2024 01:15:01 651724405   636 
27807   14.02.2024 01:30:01 651725030   625 
(missing)                   651725652.5 622.5   
27808   14.02.2024 02:00:01 651726275   622.5               2506
27809   14.02.2024 02:15:02 651726880   605 
27810   14.02.2024 02:30:01 651727519   639 
27811   14.02.2024 02:45:00 651728130   611 
27812   14.02.2024 03:00:02 651728751   621                 2476
27813   14.02.2024 03:15:02 651729381   630 

我想以某种方式需要找到两个给定时间点的最接近的两个值(例如 14.02.2024 00:00:00 和 14.02.2024 01:00:00)并创建能量计数器的插值来构建然后它的区别。

哪个查询可以达到预期的结果?

sql mysql interpolation difference linear-interpolation
1个回答
0
投票

一种选择是生成开始时间和结束时间之间的所有 15 分钟间隔 - 将间隔连接到填充缺失行的表数据 - 估算缺失的消耗量并填充缺失的行...

WITH      --  S a m p l e    D a t a :
    tbl as
        ( Select 27800 "ID", To_Date('13.02.2024 23:30:01', 'dd.mm.yyyy hh24:mi:ss') "TIME", 651720048 "ENERGY" From Dual Union All
          Select 27801, To_Date('13.02.2024 23:45:00', 'dd.mm.yyyy hh24:mi:ss'), 651720672 From Dual Union All
          --
          Select 27802,  To_Date('14.02.2024 00:15:02', 'dd.mm.yyyy hh24:mi:ss'), 651721917 From Dual Union All
          Select 27803,  To_Date('14.02.2024 00:30:00', 'dd.mm.yyyy hh24:mi:ss'), 651722540 From Dual Union All
          Select 27804,  To_Date('14.02.2024 00:45:00', 'dd.mm.yyyy hh24:mi:ss'), 651723129 From Dual Union All
          Select 27805,  To_Date('14.02.2024 01:00:02', 'dd.mm.yyyy hh24:mi:ss'), 651723769 From Dual Union All
          Select 27806,  To_Date('14.02.2024 01:15:01', 'dd.mm.yyyy hh24:mi:ss'), 651724405 From Dual Union All
          Select 27807,  To_Date('14.02.2024 01:30:01', 'dd.mm.yyyy hh24:mi:ss'), 651725030 From Dual Union All
          --
          Select 27808,  To_Date('14.02.2024 02:00:01', 'dd.mm.yyyy hh24:mi:ss'), 651726275 From Dual Union All
          Select 27809,  To_Date('14.02.2024 02:15:02', 'dd.mm.yyyy hh24:mi:ss'), 651726880 From Dual Union All
          Select 27810,  To_Date('14.02.2024 02:30:01', 'dd.mm.yyyy hh24:mi:ss'), 651727519 From Dual Union All
          Select 27811,  To_Date('14.02.2024 02:45:00', 'dd.mm.yyyy hh24:mi:ss'), 651728130 From Dual Union All
          Select 27812,  To_Date('14.02.2024 03:00:02', 'dd.mm.yyyy hh24:mi:ss'), 651728751 From Dual Union All
          Select 27813,  To_Date('14.02.2024 03:15:02', 'dd.mm.yyyy hh24:mi:ss'), 651729381 From Dual 
        ), 

创建 CTE(将其命名为间隔)以生成所有 15 分钟间隔...

--  Generate intervals of 15 minutes between first and last TIME column of your data
  intervals AS
    ( Select    MIN_TIME + ( (LEVEL - 1) * 15 ) / (24*60) "TIME", 
                To_Char(MIN_TIME + ( (LEVEL - 1) * 15 ) / (24*60), 'dd.mm.yyyy hh24:mi:ss')   "DATE_TIME"
      From
        ( Select       To_Date( To_Char(Min(Trunc(t.TIME, 'mi')), 'dd.mm.yyyy hh24:mi'), 'dd.mm.yyyy hh24:mi') "MIN_TIME", 
                       To_Date(To_Char(Max(Trunc(t.TIME, 'mi')), 'dd.mm.yyyy hh24:mi'), 'dd.mm.yyyy hh24:mi') "MAX_TIME", 
                       CEIL( ( ( Max(Trunc(t.TIME, 'mi')) - Min(Trunc(t.TIME, 'mi')) ) *24 *60 ) / 4) "DIFF"
          From         tbl t
        )
      Connect By   LEVEL <= CEIL(DIFF / 4) + 1
    )

...将间隔连接到表数据中,进行近似(需要时)并填充缺失的行...

--    M a i n    S Q L :
SELECT      Coalesce(To_Char(t.ID), 'APPROX-') || ROW_NUMBER() OVER(Partition By Case When t.TIME Is Null Then 1 End Order By t.ID) "ID",
            Coalesce(To_Char(t.TIME, 'dd.mm.yyyy hh24:mi:ss'), i.DATE_TIME) "TIME",
            Coalesce( t.ENERGY, 
                      LAST_VALUE(t.ENERGY) OVER( Order By Coalesce(t.TIME, i.TIME) Rows Between Unbounded Preceding And 1 Preceding ) + 
                      CEIL( ( LEAD(t.ENERGY) OVER(Order By Coalesce(t.TIME, i.TIME) ) - Coalesce( t.ENERGY, LAG(t.ENERGY) OVER(Order By Coalesce(t.TIME, i.TIME) ) ) ) / 2 )
                    ) "ENERGY",
            Case  When t.TIME Is Null 
                  Then  CEIL( ( LEAD(t.ENERGY) OVER(Order By Coalesce(t.TIME, i.TIME) ) - 
                               Coalesce( t.ENERGY, LAG(t.ENERGY) OVER(Order By Coalesce(t.TIME, i.TIME) ) ) ) / 2 
                           ) 
            End "APPROX_CONSUMPTION"
FROM        intervals i
Left Join   tbl t ON( Coalesce(Trunc(t.TIME, 'mi'), i.TIME) = i.TIME )
/*      R e s u l t :
ID                   TIME                 ENERGY      APPROX_CONSUMPTION
-------------------  -------------------  ----------  ------------------
278001               13.02.2024 23:30:01  651720048                   
278012               13.02.2024 23:45:00  651720672                   
APPROX-1             14.02.2024 00:00:00  651721295                  623
278023               14.02.2024 00:15:02  651721917                   
278034               14.02.2024 00:30:00  651722540                   
278045               14.02.2024 00:45:00  651723129                   
278056               14.02.2024 01:00:02  651723769                   
278067               14.02.2024 01:15:01  651724405                   
278078               14.02.2024 01:30:01  651725030                   
APPROX-2             14.02.2024 01:45:00  651725653                  623
278089               14.02.2024 02:00:01  651726275                   
2780910              14.02.2024 02:15:02  651726880                   
2781011              14.02.2024 02:30:01  651727519                   
2781112              14.02.2024 02:45:00  651728130                   
2781213              14.02.2024 03:00:02  651728751                   
2781314              14.02.2024 03:15:02  651729381                     */
© www.soinside.com 2019 - 2024. All rights reserved.