我有一张类似的桌子
create table appointments
(
id serial not null constraint appointments_pkey primary key,
patient_id varchar(255) not null,
date timestamp(0) not null
);
我想在单个查询中获取下一个约会和上一个约会的日期。
我创建的查询方式为
SELECT
(
SELECT MIN(ap.date) FROM appointments ap
WHERE ap.date >= NOW() AND ap.patient_id = '1'
) AS next,
(
SELECT MAX(ap.date) FROM appointments ap
WHERE ap.date < NOW() AND ap.patient_id = '1'
) AS last
可以按预期工作,但是我认为由于两个子查询,它没有得到优化。 请您帮我优化这样的查询吗?
答案 0 :(得分:2)
您可以使用case when expression
select
min(case when ap.date >= NOW() then ap.date end) next,
max(case when ap.date < NOW() then ap.date end) last
from appointments ap
where ap.patient_id = '1'
答案 1 :(得分:0)
您的方法可能很好。我更可能使用union all
来实现此目的,
(SELECT ap.*
FROM appointments ap
WHERE ap.patient_id = 1 AND ap.date >= NOW()
ORDER BY ap.date DESC
FETCH FIRST 1 ROW ONLY
) UNION ALL
(SELECT ap.*
FROM appointments ap
WHERE ap.patient_id = 1 AND ap.date < NOW()
ORDER BY ap.date ASC
FETCH FIRST 1 ROW ONLY
) ;
这将返回整个行,而不仅仅是日期。
通过该查询,您都可以利用appointments(patient_id, date)
上的索引。其他解决方案(例如条件聚合和窗口函数)可能不会利用索引,因此需要扫描整个表。