我正在尝试找到一种方法,根据前面值的逻辑为下一列赋值。例如,假设我们有一个包含temp列的表。如果temp超过95,则表应显示为"系统关闭",如果下一个值大于80,则状态列仍显示为"系统关闭",仅当下一个值小于80时,此状态才会更改。请参阅示例:
| 位置ID|事件时间|温度|系统状态:所需列(有效连续值)|
| - ------|- ------|- ------|- ------|
| 九九九九九九九九九九九九|下午4时18分58秒|八十点三|"系统开启"|
| 九九九九九九九九九九九九|下午4时21分03秒|七十点五|"系统开启"|
| 九九九九九九九九九九九九|下午4时21分42秒|九十六点二|"系统关闭"|
| 九九九九九九九九九九九九|下午4时25分04秒|九十五点三|"系统关闭"|
| 九九九九九九九九九九九九|下午4时25分40秒|八十二点一|"系统关闭"|
| 九九九九九九九九九九九九|下午4时25分45秒|七十九岁|"系统开启"|
| 九九九九九九九九九九九九|下午4时26分14秒|95分|"系统关闭"|
| 九九九九九九九九九九九九|下午4时26分23秒|七十二岁|"系统开启"|
下面是我尝试过的SQL,但它并不像我希望的那样工作。
> ```
> WITH input_data AS (
SELECT *,
CASE
WHEN Temp >= 95 THEN 'System Off'
ELSE 'System On'
END AS valid_current_value
FROM table
),
consecutive_values AS (
SELECT *,
SUM(CASE
WHEN valid_current_value = 'System Off' THEN 1
ELSE 0
END)
OVER (ORDER BY Event_Time
ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS consecutive_falses
FROM input_data
),
consecutive_values_above_80 AS (
SELECT *,
SUM(CASE
WHEN Temp >= 80 THEN 1
ELSE 0
END)
OVER (ORDER BY Event_Time
ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS consecutive_values_above_80
FROM consecutive_values
)
SELECT *,
CASE
WHEN consecutive_falses >= 2 OR consecutive_values_above_80 >= 2 THEN 'System Off'
ELSE 'System On'
END AS valid_consecutive_values
FROM consecutive_values_above_80
> ```
逻辑:如果当前单元格为95,则"系统关闭"。如果下一个值大于80,则"系统关闭"。此逻辑将继续,直到在下一行中找到小于80的值。一旦我们看到小于80的值,则状态更改为"系统打开"。请注意,只有在前面的值为95且后面的值大于80时,此逻辑才起作用。
DESIRED OUTPUT EXAMPLE
1条答案
按热度按时间dtcbnfnu1#
这是一个间隙和孤岛问题,您可以尝试以下方法来解决它,查询注解中的解释:
Check this demo(MySQL上)基于发布的图像中提供的示例数据。