对于这个问题,我正在使用2个主要的现有postgres表。第一个表名为客户端,第二个表名为任务。
单个客户端可以拥有多个任务,每个任务都有自己的scheduled_date和scheduled_time。
我试图运行一个查询,该查询将返回所有客户的列表以及最新任务的日期/时间。
目前,我的查询有效并且看起来像这样......
SELECT
c.*,
t1.scheduled_time||' '||t1.scheduled_time::timestamp AS latest_task_datetime
FROM
client c
LEFT JOIN
task t1 ON t1.client_id = c.client_id
LEFT JOIN
task t2 ON t2.client_id = t1.client_id AND ((t1.scheduled_date||' '||t1.scheduled_time)::timestamp < (t2.scheduled_date||' '||t2.scheduled_time)::timestamp) OR ((t1.scheduled_date||' '||t1.scheduled_time)::timestamp = (t2.scheduled_date||' '||t2.scheduled_time)::timestamp AND t1.task_id < t2.task_id);
我遇到的问题是我正在处理的实际查询涉及更多其他表(7+表),并且每个表中都有大量数据,因此有两个左连接如上所示,它将查询的执行速度从4秒减慢到接近45秒,这当然非常糟糕。
是否有人知道编写此查询以更有效地运行的更快方法?
我认为您在看到这个之后可能最初会遇到的问题是我将scheduled_date和scheduled_time作为单独的列的原因?为什么不将它作为单个时间戳列?答案就是这是一个我无法改变的现有表格,至少不容易,不需要在整个服务器上进行大量工作来支持它。
编辑:不完全是解决方案,但我最后以不同的方式做到了。 (见下面的评论)
答案 0 :(得分:0)
如果您想从不同的表中获取多列信息 - 但每个客户一行和他/她的最新任务,那么您可以使用distinct on
:
SELECT DISTINCT ON (c.client_id) c.*, t.*
FROM client c LEFT JOIN
task t
ON t.client_id = c.client_id
ORDER BY c.client_id, t.scheduled_date desc, t.scheduled_time desc;