Below query is just taking long time and the below predicate is used only to get unique records, as such was wondering is there a different way to rewrite the same query without calling the below predicate multiple times, to get the unique ID.
select max(c.id) from plocation c where c.ids = y.ids and c.idc = y.idc)
select max(cr.id) from plocation_log cr where cr.ids = yt.ids and cr.idc = yt.idc)
select max(pr.id) from patentpr where pr.ids = p.ids and pr.idc = p.idc)
My full sample query
SELECT to_char(p.pid) AS patentid,
p.name,
x.dept,
y.location
FROM patent p
JOIN pdetails x ON p.pid = x.pid AND x.isactive = 1
JOIN plocation y
ON y.idr = p.idr
AND y.idc = p.idc
AND y.id = *(select max(c.id) from plocation c where c.ids = y.ids and c.idc = y.idc)*
AND y.idopstype in (36, 37)
JOIN plocation_log yt
ON yt.idr = y.idr
AND yt.idc= y.idc
AND yt.id = *(select max(cr.id) from plocation_log cr where cr.ids = yt.ids and cr.idc = yt.idc)*
AND yt.idopstype in (36,37)
WHERE
p.idp IN (10,20,30)
AND p.id = *(select max(pr.id) from patent pr where pr.ids = p.ids and pr.idc = p.idc)*
AND p.idopstype in (36,37)
As commented by The Impaler, one option is to use analytic functions instead of correlated subqueries. The idea is to rank records within subqueries using RANK()
, then filter in the outer query (join conditions or WHERE
clause).
Consider:
SELECT to_char(p.pid) AS patentid,
p.name,
x.dept,
y.location
FROM (SELECT p.*, RANK() OVER(PARTITION BY ids, idc ORDER BY id) rn FROM patinet) p
JOIN pdetails x ON p.pid = x.pid AND x.isactive = 1
JOIN (SELECT y.*, RANK() OVER(PARTITION BY ids, idc ORDER BY id) rn FROM plocation y) y
ON y.idr = p.idr
AND y.idc = p.idc
AND y.idopstype in (36, 37)
AND y.rn = 1
JOIN (SELECT y.*, RANK() OVER(PARTITION BY ids, idc ORDER BY id) rn FROM plocation_log yt) yt
ON yt.idr = y.idr
AND yt.idc= y.idc
AND yt.idopstype in (36,37)
AND yt.rn = 1
WHERE
p.idp IN (10,20,30)
AND p.idopstype in (36,37)
AND p.rn = 1
Consider joining to aggregate CTEs to calculate MAX
values per group once as opposed to rowwise MAX
calculation for every outer query row. Also, be sure to use more informative table aliases instead of a, b, c
or x, y, z
style.
WITH loc_max AS
(select ids, idc, max(id) as max_id from plocation group ids, idc)
, log_max AS
(select ids, idc, max(id) as max_id from plocation_log group by ids, idc)
, pat_max AS
(select ids, idc, max(id) as max_id from patent pr group by ids, idc)
SELECT to_char(pat.pid) AS patentid
, pat.name
, det.dept
, loc.location
FROM patent pat
JOIN pdetails det
ON pat.pid = det.pid
AND det.isactive = 1
JOIN plocation loc
ON loc.idr = pat.idr
AND loc.idc = pat.idc
AND loc.idopstype IN (36, 37)
JOIN loc_max -- ADDED CTE JOIN
ON loc.id = loc_max.max_id
AND loc.ids = loc_max.ids
AND loc.idc = loc_max.idc
JOIN plocation_log log
ON log.idr = log.idr
AND log.idc = log.idc
AND log.idopstype in (36,37)
JOIN log_max -- ADDED CTE JOIN
ON log.id = log_max.max_id
AND log.ids = log_max.ids
AND log.idc = log_max.idc
JOIN pat_max -- ADDED CTE JOIN
ON pat.id = pat_max.max_id
AND pat.ids = pat_max.ids
AND pat.idc = pat_max.idc
WHERE pat.idp IN (10, 20, 30)
AND pat.idopstype IN (36, 37)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.