子查询中的PostGreSql ISNULL或Coalesce



嗯,我有一个带有时间戳列的表。我必须返回该表中的所有记录,其中时间戳在给定的时间点(=timeX(之后,但加上最后一个记录timeX。

我的方法是按照时间戳对条目进行编号。然后再选择timeX(=numX(之后第一条记录的编号。并返回数字大于numX-1的所有记录。

测试设置

CREATE TABLE public.events
(
id integer,
name character varying(50) COLLATE pg_catalog."default",
happens timestamp without time zone
);
INSERT INTO events (id, name, happens)
VALUES
(1, 'event 7', '2018-08-01 07:00:00.000000'),
(2, 'event 6', '2018-08-01 06:00:00.000000'),
(3, 'event 2', '2018-08-01 02:00:00.000000'),
(4, 'event 5', '2018-08-01 05:00:00.000000'),
(5, 'event 1', '2018-08-01 01:00:00.000000'),
(6, 'event 8', '2018-08-01 08:00:00.000000'),
(7, 'event 5.2', '2018-08-01 05:00:00.000000'),
(8, 'event 4', '2018-08-01 04:00:00.000000'),
(9, 'event 3', '2018-08-01 03:00:00.000000');

我当前的查询

WITH AllEvents AS (
SELECT
ROW_NUMBER() OVER (ORDER BY happens) AS num,
id,
name,
happens
FROM events
ORDER BY num
)
SELECT * FROM AllEvents ae
WHERE ae.num >= 
(
SELECT Num-1
FROM AllEvents
WHERE happens >= '2018-08-01 02:30:00'
LIMIT 1
);

查询在"2018-08-01 02:30:00"运行良好,因为select查找可以返回num的条目。

如果我尝试选择"2018-08-01 17:30:00",则查询找不到记录,因此返回的num为null,结果是一个空列表,而不是最后一条记录。

我试着用ISNULL或COALESCE和MAX(ae.num(来解决这个问题,但我无法让它发挥作用。

任何提示我可以完成空检查并返回最后一条记录(这将等于Max(ae.num(??

这不是更简单吗?:

select * from events
where happens >= 
(select max(happens) from events
WHERE happens < '2018-08-01 02:30:00');

我真的不明白您想要实现的逻辑是什么。因此,可能有一种更简单的方法来实现你想要的。

但是,您可以将子查询作为一个参数来修复您的查询:

WHERE ae.num >= COALESCE((SELECT ae2.Num - 1
FROM AllEvents ae2
WHERE ae2.happens >= '2018-08-01 02:30:00'
LIMIT 1
), ae.num
);

您还会注意到,我向子查询添加了表别名和限定列名。这是避免使用子查询时出现问题的最佳做法。

最新更新