将多个左连接合并为一个

问题描述 投票:0回答:1

这是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数量较多,导致客户端的请求处理时间较长。

postgresql
1个回答
0
投票

您可以使用聚合

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
© www.soinside.com 2019 - 2024. All rights reserved.