检测两个或多个连续行是否具有与sql查询相同的条目

检测两个或多个连续行是否具有与sql查询相同的条目,sql,postgresql,Sql,Postgresql,我的数据库中有一个警报表,用于存储我的web应用程序状态代码。这些状态代码是从用python编写的任务调度器获得的,该任务调度器定期查询前端和后端api,并将响应中返回的结果状态代码存储到各自的列中:前端_状态和后端_状态 我正在尝试做一个简单的sql查询,检查其中一列中的两个或多个连续条目是否不是200,这意味着可能有错误。如果是,我想使用布尔值来执行操作。我不确定我是否遗漏了一些明显的东西,但一些帮助会很好 我在postgres中创建了一个表,如下所示: -- Table: public.a

我的数据库中有一个警报表,用于存储我的web应用程序状态代码。这些状态代码是从用python编写的任务调度器获得的,该任务调度器定期查询前端和后端api,并将响应中返回的结果状态代码存储到各自的列中:前端_状态和后端_状态

我正在尝试做一个简单的sql查询,检查其中一列中的两个或多个连续条目是否不是200,这意味着可能有错误。如果是,我想使用布尔值来执行操作。我不确定我是否遗漏了一些明显的东西,但一些帮助会很好

我在postgres中创建了一个表,如下所示:

-- Table: public.alert_001

-- DROP TABLE public.alert_001;

CREATE TABLE public.alert_001
(
    data_id integer NOT NULL DEFAULT nextval('alert_001_data_id_seq'::regclass),
    when_captured timestamp without time zone NOT NULL,
    frontend_status real,
    backend_status real,
    CONSTRAINT alert_001_pkey PRIMARY KEY (data_id)
)
WITH (
    OIDS = FALSE
)
TABLESPACE pg_default;

ALTER TABLE public.alert_001
    OWNER to postgres;

-- Index: alert_001_when_index

-- DROP INDEX public.alert_001_when_index;

CREATE INDEX alert_001_when_index
    ON public.alert_001 USING btree
    (when_captured)
    TABLESPACE pg_default;
然后,我设法编写了一个查询,对过去一小时内具有特定值的条目数进行计数。例如,如果计数的条目超过2,它将返回布尔值true。然而,尽管在最后一个小时内拾取两个条目时,这种方法仍然有效,但它们不一定是连续条目。因此,我的sql查询类似于:

SELECT (SELECT COUNT(*) AS "Count" 
FROM alert_001 WHERE when_captured > NOW() - '1 hour'::INTERVAL AND backend_status != 200) > 2
有人能给我指出正确的方向来捕捉三个或更多状态代码不是200的连续条目吗

以下是alert_001表中的条目示例:

when_captured,frontend_status, backend_status
'2018-02-02 14:55:19.63941','200','200'
'2018-02-02 14:54:19.636386','200','503'
'2018-02-02 14:53:19.636055','200','503'
'2018-02-02 14:52:19.631958','200','503'
'2018-02-02 14:51:19.62166','200','200'
'2018-02-02 14:50:19.621363','200','200'
'2018-02-02 14:49:19.612434','200','200'
'2018-02-02 14:48:19.611919','200','200'
'2018-02-02 14:47:19.610065','200','200'
'2018-02-02 14:46:19.607846','200','200'

正如您所看到的,有三个连续的条目,它们的状态代码为503,我想捕获。因此,如果找到三个以上的sql查询,则正确sql查询的预期输出可能为True,否则为False

您应该为此使用窗口函数:

SELECT EXISTS (
   SELECT 1 FROM
      (SELECT data_id,
              backend_status status,
              lag(backend_status) OVER w status_1,
              lag(backend_status, 2) OVER w status_2
         FROM alert_001
         WHERE when_captured > current_timestamp - INTERVAL '1 hour'
         WINDOW w AS (ORDER BY when_captured)
      ) last_three
   WHERE status <> 200
     AND status_1 <> 200
     AND status_2 <> 200
);

@我添加了一些示例数据,以及如果找到三个或更多连续条目时的预期输出。感谢@Laurenz Albe,您的sql查询很好地捕捉到了三个或更多连续行的状态代码不是200的情况,但如何仅在发生一次时才捕捉到它,并在发生这种情况时返回布尔值True?哦,很简单。使用EXISTS包装整个查询。