这是sql请求
SELECT ot.id, ot.parent_id, ot.id_object_types AS object_type, ot.object_code, ot.name,
u.login, u.last_seen, u.pass_upd, u.pass_default, ct.citizens_total, fl.downloaded as files_downloaded, fl.total AS files_total,
ct0.type0, ct1.type1, ct2.type2
FROM public.object_tree AS ot
LEFT JOIN admin.admin_user AS u ON ot.object_code = u.r8012
LEFT JOIN (select object_code, count(uploaded)::int as total, count(downloaded)::int as downloaded
from web.files f group by object_code) as fl ON fl.object_code = ot.object_code
LEFT JOIN (select distinct ct.code_obj AS object_code, count(ct.citizens_id)::int as citizens_total
from tbd.citizens_vk ct WHERE ct.actual = 1 group by ct.code_obj) as ct ON ct.object_code = ot.object_code
LEFT JOIN (select distinct ct.code_obj AS object_code, count(ct.citizens_id)::int as type0
from tbd.citizens_vk ct WHERE ct.type_db = '0' AND ct.actual = 1 group by ct.code_obj) as ct0 ON ct0.object_code = ot.object_code
LEFT JOIN (select distinct ct.code_obj AS object_code, count(ct.citizens_id)::int as type1
from tbd.citizens_vk ct WHERE ct.type_db = '1' AND ct.actual = 1 group by ct.code_obj) as ct1 ON ct1.object_code = ot.object_code
LEFT JOIN (select distinct ct.code_obj AS object_code, count(ct.citizens_id)::int as type2
from tbd.citizens_vk ct WHERE ct.type_db = '2' AND ct.actual = 1 group by ct.code_obj) as ct2 ON ct2.object_code = ot.object_code
WHERE ot.id IN ( $1:csv )
ORDER BY ot.id
是否可以减少 tbd.citizen_vk 表的联接数量? 因为由于join数量较多,导致客户端的请求处理时间较长。
您可以使用聚合
filter
子句在一次扫描中获取三个不同的计数,并使用单个 join
:
SELECT ot.id, ot.parent_id, ot.id_object_types AS object_type, ot.object_code, ot.name,
u.login, u.last_seen, u.pass_upd, u.pass_default,
ct.citizens_total,
fl.downloaded as files_downloaded, fl.total AS files_total,
ct0.type0, ct0.type1, ct0.type2
FROM public.object_tree AS ot
LEFT JOIN admin.admin_user AS u
ON ot.object_code = u.r8012
AND ot.id IN ( $1:csv )
LEFT JOIN (
select object_code,
count(uploaded)::int as total,
count(downloaded)::int as downloaded
from web.files f
group by object_code) AS fl USING(object_code)
LEFT JOIN (
select ct.code_obj AS object_code,
count(ct.citizens_id)::int as citizens_total
from tbd.citizens_vk ct
WHERE ct.actual = 1
group by ct.code_obj) AS ct USING(object_code)
LEFT JOIN (
select ct.code_obj AS object_code,
(count(ct.citizens_id)filter(where ct.type_db ='0'))::int AS type0,
(count(ct.citizens_id)filter(where ct.type_db ='1'))::int AS type1,
(count(ct.citizens_id)filter(where ct.type_db ='2'))::int AS type2,
from tbd.citizens_vk ct
WHERE ct.type_db IN ('0', '1', '2')
AND ct.actual = 1
group by ct.code_obj) AS ct0 USING(object_code)
ORDER BY ot.id