我有一个小的要求要解决。
我们有每半小时记录的数据从一天开始的27-09-2018 00:00:00开始。
Meter_id |Realtimeclock |I_Y|I_B|I_X|
201010 |27-09-2018 00:00:00|1.0|2.0|3.0|
201010 |27-09-2018 00:30:00|1.0|2.0|3.0|
201010 |27-09-2018 01:00:00|1.0|2.0|3.0|
201010 |27-09-2018 01:30:00|1.0|2.0|3.0|
201010 |27-09-2018 02:00:00|1.0| 0 |3.0|
201010 |27-09-2018 02:30:00|1.0| 0 |0 |
201010 |27-09-2018 03:00:00|1.0|2.0|3.0|
201010 |27-09-2018 03:30:00|1.0|2.0|3.0|
从上表中,我们必须获取从realtimeclock的27-09-2018 00:00:00到realtimeclock的27-09-2018 01:30:00的数据作为一项记录, 并看到在两个时间戳27-09-2018 02:00:00和27-09-2018 02:30:00的I_B和I_X中都有值0,因此在这里我们可以跳过这两个记录并继续处理剩余数据它开始于realtimeclock的27-09-2018 03:00:00并结束于27-09-2018 03:30:00,并且应该表示为另一个带有count的记录。
就像这里的输出应该是
Meter_id |start_time |End_time |I_Y|I_B|I_X|
201010 |27-09-2018 00:00:00|27-09-2018 01:30:00|4 |4 |4 |
201010 |27-09-2018 03:00:00|27-09-2018 03:30:00|2 |2 |2 |
答案 0 :(得分:0)
这是一个空白和孤岛的问题。一种方法使用行数差异方法:
WITH cte1 AS (
SELECT t.*, ROW_NUMBER() OVER (PARTITION BY Meter_id ORDER BY Realtimeclock) rn
FROM yourTable t
),
cte2 AS (
SELECT t.*, ROW_NUMBER() OVER (PARTITION BY Meter_id ORDER BY Realtimeclock) rn
FROM yourTable t
WHERE I_B <> 0
),
cte3 AS (
SELECT t1.*,
t1.rn - t2.rn AS diff
FROM cte1 t1
INNER JOIN cte2 t2
ON t1.Meter_id = t2.Meter_id AND t1.Realtimeclock = t2.Realtimeclock
)
SELECT
Meter_id,
MIN(Realtimeclock) AS start_time,
MAX(Realtimeclock) AS end_time,
COUNT(I_Y) AS I_Y,
COUNT(I_B) AS I_B,
COUNT(I_X) AS I_X
FROM cte3
GROUP BY
Meter_id,
diff;
注意:该演示位于SQL Server中,但代码也应在Oracle上运行,无需进行任何修改。有时在设置演示时会遇到Oracle语法的问题。
答案 1 :(得分:0)
我认为您要么需要编写一个存储过程,就可以在指定条件下运行循环并获取记录,类似于以下内容:
Row for each hour even if there is no record [duplicate]
或者您每1小时或您需要的任何时间间隔执行一次查询,传递所有更新的数据并获得结果,在这种情况下,查询可以是这样的:
从table_name中选择*,其中start_datetime和end_datetime之间的实时时间,并且I_B!= 0和I_X!= 0;
如果任何条件错误,它将返回一个空集。