我想找到仍然没有近期活动的旧工作。
表格如下:
CREATE TABLE job
(jobid int4, jobname text, jobdate date);
INSERT INTO job
(jobid, jobname, jobdate)
VALUES
(1,'X','2016-12-31'),
(2,'Y','2016-12-31'),
(3,'Z','2016-12-31');
CREATE TABLE hr
(hrid int4, hrjob int4, hrdate date);
INSERT INTO hr
(hrid, hrjob, hrdate)
VALUES
(1,1,'2017-05-30'),
(2,1,'2016-12-31'),
(3,2,'2016-12-31'),
(4,3,'2016-12-31'),
(5,4,'2017-12-31');
CREATE TABLE po
(poid int, pojob int4, podate date);
INSERT INTO po
(poid, pojob, podate)
VALUES
(1,1,'2016-05-30'),
(2,1,'2016-12-31'),
(3,2,'2016-12-31'),
(4,3,'2016-12-31'),
(5,4,'2017-12-31');
我找到了一个适用于少量记录的解决方案,但需要花费很长时间才能完成数千条记录
SELECT jobid
FROM job
LEFT JOIN hr ON hrjob=jobid
LEFT JOIN po ON poid=jobid
WHERE jobdate <'2017-12-31'
GROUP BY jobid
HAVING greatest(max(hrdate),max(podate))<'2017-12-31'
ORDER BY jobid
有没有办法简化和加快这个查询?
在这种情况下,除了4之外的所有工作都可以关闭=没有最近的活动。
SQLFiddle:http://sqlfiddle.com/#!15/098c3/1
执行计划:
GroupAggregate (cost=311.82..1199.60 rows=67 width=12)
Filter: (GREATEST(max(hr.hrdate), max(po.podate)) < '2017-12-31'::date)
-> Merge Left Join (cost=311.82..925.66 rows=36414 width=12)
Merge Cond: (job.jobid = po.poid)
-> Merge Left Join (cost=176.48..234.72 rows=3754 width=8)
Merge Cond: (job.jobid = hr.hrjob)
-> Sort (cost=41.13..42.10 rows=387 width=4)
Sort Key: job.jobid
-> Seq Scan on job (cost=0.00..24.50 rows=387 width=4)
Filter: (jobdate < '2017-12-31'::date)
-> Sort (cost=135.34..140.19 rows=1940 width=8)
Sort Key: hr.hrjob
-> Seq Scan on hr (cost=0.00..29.40 rows=1940 width=8)
-> Sort (cost=135.34..140.19 rows=1940 width=8)
Sort Key: po.poid
-> Seq Scan on po (cost=0.00..29.40 rows=1940 width=8)
说明:
Output: job.jobid
Filter: (GREATEST(max(hr.hrdate), max(po.podate)) < '2017-12-31'::date)
-> Merge Left Join (cost=311.82..925.66 rows=36414 width=12) (actual time=0.032..0.039 rows=4 loops=1)
Output: job.jobid, hr.hrdate, po.podate
Merge Cond: (job.jobid = po.poid -> Merge Left Join (cost=176.48..234.72 rows=3754 width=8) (actual time=0.024..0.028 rows=4 loops=1)
Output: job.jobid, hr.hrdate
Merge Cond: (job.jobid = hr.hrjob -> Sort (cost=41.13..42.10 rows=387 width=4) (actual time=0.014..0.015 rows=3 loops=1)
Output: job.jobid
Sort Key: job.jobid
Sort Method: quicksort Memory: 25kB -> Seq Scan on public.job (cost=0.00..24.50 rows=387 width=4) (actual time=0.006..0.007 rows=3 loops=1)
Output: job.jobid
Filter: (job.jobdate < '2017-12-31'::date) -> Sort (cost=135.34..140.19 rows=1940 width=8) (actual time=0.008..0.009 rows=5 loops=1)
Output: hr.hrdate, hr.hrjob
Sort Key: hr.hrjob
Sort Method: quicksort Memory: 25kB -> Seq Scan on public.hr (cost=0.00..29.40 rows=1940 width=8) (actual time=0.001..0.002 rows=5 loops=1)
Output: hr.hrdate, hr.hrjob -> Sort (cost=135.34..140.19 rows=1940 width=8) (actual time=0.007..0.007 rows=5 loops=1)
Output: po.podate, po.poid
Sort Key: po.poid
Sort Method: quicksort Memory: 25kB -> Seq Scan on public.po (cost=0.00..29.40 rows=1940 width=8) (actual time=0.001..0.003 rows=5 loops=1)
Output: po.podate, po.poid
Total runtime: 0.148 ms
提前谢谢
答案 0 :(得分:1)
您可以找到像这样的旧作业
,而不是使用JOIN和GROUP BYSELECT jobid
FROM job
WHERE jobdate < '2017-12-31'
AND NOT EXISTS (SELECT 1
FROM hr
WHERE hr.hrjob = job.jobid
AND hrdate >= '2017-12-31')
AND NOT EXISTS (SELECT 1
FROM po
WHERE po.poid = job.jobid
AND podate >= '2017-12-31')
ORDER BY jobid
我认为它可以加快您的查询速度。
答案 1 :(得分:0)
可以为您节省大量潜在处理的事情是向作业添加一个字段,指示作业已关闭。这可以为您节省大量的查询工作!