SQL 如何获取和使用以前的数据并在以后计算
Posted
技术标签:
【中文标题】SQL 如何获取和使用以前的数据并在以后计算【英文标题】:SQL How to get and use previous data and calculate later 【发布时间】:2020-05-12 23:38:30 【问题描述】:这是我拥有的数据:
+-----+-------------+----------+-----------+
| id | date | status | health |
+-----+-------------+----------+-----------+
| 270 | 4/5/20 3:00 | STARTING | UNHEALTHY |
| 270 | 4/5/20 3:03 | ACTIVE | UNHEALTHY |
| 270 | 4/5/20 3:05 | ACTIVE | UNHEALTHY |
| 270 | 4/5/20 3:08 | ACTIVE | HEALTHY |
| 270 | 4/5/20 3:14 | ACTIVE | UNHEALTHY |
+-----+-------------+----------+-----------+
我想计算由 STARTING 引起的停机时间(在本例中,从 4/5/20 3:03 ~ 4/5/20 3:08 开始)。
这是我希望的结果:
+-----+-------------+----------+-----------+-------------------------------------+
| id | date | status | health | STARTING_CAUSED_DOWNTIME_IN_SECONDS |
+-----+-------------+----------+-----------+-------------------------------------+
| 270 | 4/5/20 3:00 | STARTING | UNHEALTHY | |
| 270 | 4/5/20 3:03 | ACTIVE | UNHEALTHY | |
| 270 | 4/5/20 3:05 | ACTIVE | UNHEALTHY | |
| 270 | 4/5/20 3:08 | ACTIVE | HEALTHY | 480 |
| 270 | 4/5/20 3:14 | ACTIVE | UNHEALTHY | |
+-----+-------------+----------+-----------+-------------------------------------+
如果你看到这个,我没有考虑最后一行,ACTIVE / UNHEALTHY (3:14),因为它不是 STARTING 导致停机(这意味着开始后不健康)
我尝试过的:
SELECT
id,date,status,prev_status,health,prev_health,LAST_START_TIME,HEALTHY_AFTER_STARTING_TIME
FROM
(
SELECT
id,date,status,health,
LAG(status) OVER(partition BY id ORDER BY DATE) AS prev_status,
LAG(health) OVER (partition BY id ORDER BY DATE) AS prev_health,
(case when status = 'ACTIVE' AND prev_status = 'STARTING' then date end) AS LAST_START_TIME,
(case when status = 'ACTIVE' AND prev_status = 'ACTIVE' AND prev_health = 'UNAVAILABLE' AND health_state <> 'UNAVAILABLE' THEN date END) AS HEALTHY_AFTER_STARTING_TIME
FROM
DB_TABLE_04
) t1 ORDER BY DATE
我尝试使用此查询查找 2 次(STARTING 停机时间开始时/STARTING 停机时间结束时)。
我发现了 2 个问题。
-
当我找到第二次,当 STARTING 停机时间结束时 (HEALTHY_AFTER_STARTING_TIME),我无法弄清楚如何找到停机时间。
我认为它需要类似于:
(extract(epoch from (starting_downtime_end - most_recent_starting_downtime_start)))
但是我该如何实现呢?
-
这是更大的问题。如果我采用这种方法,我最终会考虑所有活动/不健康的情况,即使它不是由开始引起的
例如,它将创建如下内容:
+-----+-------------+----------+-------------+-----------+-------------+-----------------+-----------------------------+
| id | date | status | prev_status | health | prev_health | LAST_START_TIME | HEALTHY_AFTER_STARTING_TIME |
+-----+-------------+----------+-------------+-----------+-------------+-----------------+-----------------------------+
| 270 | 4/5/20 3:00 | STARTING | | UNHEALTHY | | | |
| 270 | 4/5/20 3:03 | ACTIVE | STARTING | UNHEALTHY | UNHEALTHY | 4/5/20 3:00 | |
| 270 | 4/5/20 3:05 | ACTIVE | ACTIVE | UNHEALTHY | UNHEALTHY | | |
| 270 | 4/5/20 3:08 | ACTIVE | ACTIVE | HEALTHY | UNHEALTHY | | 4/5/20 3:08 |
| 270 | 4/5/20 3:14 | ACTIVE | ACTIVE | UNHEALTHY | HEALTHY | | |
| 270 | 4/5/20 3:18 | ACTIVE | ACTIVE | HEALTHY | UNHEALTHY | | 4/5/20 3:18 |
+-----+-------------+----------+-------------+-----------+-------------+-----------------+-----------------------------+
我不想考虑 4/5/20 3:18 的情况,但它会。
如何从数据中获得我想要的结果?
我也可以在这个问题中使用窗口函数吗?
【问题讨论】:
我删除了不一致的数据库标签。请仅使用您真正使用的数据库进行标记。 @GordonLinoff 谢谢,我开始学习 sql 作为 sql-server,但目前正在研究 redshift。这就是我添加两者的原因。从现在开始,我会将它保留到我目前正在处理的那个。 【参考方案1】:嗯。 . .这似乎得到了你想要的日期:
select t.*,
(case when health = 'HEALTHY'
then max(case when status = 'STARTING' then date end) over
(partition by id
order by date
rows between unbounded preceding and current row
)
end) as starting_date
from DB_TABLE_04 t;
以及以秒为单位的差异:
datediff(second,
(case when health = 'HEALTHY'
then max(case when status = 'STARTING' then date end) over
(partition by id
order by date
rows between unbounded preceding and current row
)
end),
date
) as seconds_diff
此外,窗口框架子句 (rows between
) 在 SQL Server 中是不必要的,但在 Redshift 中是必需的。
【讨论】:
谢谢,我也快到这里了,但是通过这种方法,我关心的第二个问题仍然出现在结果中。我只想在它变为 ACTIVE 时显示一次结果编号 |不健康到活跃 |健康的每个开始状态。使用这种方法,我的上一个示例中的 4/5/20 3:08 和 4/5/20 3:18 案例都会显示数字,我不想显示 4/5/20 3:18向上。有什么技巧可以将您现在拥有的内容修改为我想要的内容吗?感觉快到了,但我被困在这里 使用这种方法,starting_date 将继续显示,并且仅在新的开始事件发生时更改它的日期,并且每次健康状况良好时都会尝试 datediff,我想要的是停机时间导致 STARTING。有点不同以上是关于SQL 如何获取和使用以前的数据并在以后计算的主要内容,如果未能解决你的问题,请参考以下文章
如何在计算机中训练神经网络或随机森林算法并在以后的Android设备中进行测试?
如何在 SQL Server 中使用存储过程提高和加快获取数据的速度?