Необработанный SQL-запрос выглядит странно, ищет лучший способ

#sql #postgresql

#sql #postgresql

Вопрос:

У меня редко была возможность написать необработанный SQL-запрос, я написал этот запрос, но чувствую, что с ним что-то не так. Интересно, есть ли лучший способ его написать. Может быть, я узнаю что-то новое.

 select a.approved, c.review, d.pending, f.total, f.total - a.approved - c.review as ongoing
from
 (select count(distinct sownumber) as approved from v_scope_of_work_combined where name = 'CTN-Approve' and assigned_engineer_my_tasks = 'NotClaimed' and sow_status = 'PM Approved'  and implementer = 'C1') as a,
 (select count(distinct sownumber) as review from v_scope_of_work_combined where name = 'CTN-Approve' and assigned_engineer_my_tasks != 'NotClaimed'and sow_status = 'PM Approved'  and implementer = 'C1') as c,
 (select count(distinct sownumber) as pending from v_scope_of_work_combined where name = 'CTN-Approve' and v_scope_of_work_combined.design_readiness = 'No'and sow_status = 'PM Approved'  and implementer = 'C1') as d,
 (select count(distinct sownumber) as total from v_scope_of_work_combined where  sow_status = 'PM Approved'  and implementer = 'C1') as f;
 

Ответ №1:

Вы можете улучшить это, используя фильтрованную агрегацию:

 select approved, review, pending, total, total - approved - review as ongoing
from (
  select count(distinct sownumber) filter (where name = 'CTN-Approve' and assigned_engineer_my_tasks = 'NotClaimed') as approved,
         count(distinct sownumber) filter (where name = 'CTN-Approve' and assigned_engineer_my_tasks != 'NotClaimed') as review,
         count(distinct sownumber) filter (where name = 'CTN-Approve' and design_readiness = 'No' )  as pending,
         count(distinct sownumber) as total 
  from v_scope_of_work_combined 
  where implementer = 'C1'
    and sow_status = 'PM Approved'
) t
 

Комментарии:

1. Конечно, это немного чище, чем моя версия. Спасибо

Ответ №2:

Вы можете написать условную агрегацию следующим образом:

 select approved, review, pending, total, total - approved - review as ongoing
from (
  select count(distinct sownumber) filter (where name = 'CTN-Approve' and assigned_engineer_my_tasks = 'NotClaimed' and implementer = 'C1' and sow_status = 'PM Approved') as approved,
         count(distinct sownumber) filter (where name = 'CTN-Approve' and assigned_engineer_my_tasks != 'NotClaimed' and implementer = 'C1' and sow_status = 'PM Approved') as review,
         count(distinct sownumber) filter (where name = 'CTN-Approve' and design_readiness = 'No' and implementer = 'C1' and sow_status = 'PM Approved')  as pending,
         count(distinct sownumber) filter (where implementer = 'C1' and sow_status = 'PM Approved') as total 
  from v_scope_of_work_combined t) t
 

Ответ №3:

Я думаю, что написание такого рода запросов без нескольких подзапросов более читаемо.

 SELECT 
    COUNT(DISTINCT CASE WHEN name = 'CTN-Approve' and assigned_engineer_my_tasks = 'NotClaimed' and sow_status = 'PM Approved'  and implementer = 'C1' THEN sownumber ELSE NULL END) 
        AS approved,
    
    COUNT(DISTINCT CASE WHEN name = 'CTN-Approve' and assigned_engineer_my_tasks != 'NotClaimed'and sow_status = 'PM Approved'  and implementer = 'C1' THEN sownumber ELSE NULL END) 
        AS review,
    
    COUNT(DISTINCT CASE WHEN name = 'CTN-Approve' and v_scope_of_work_combined.design_readiness = 'No'and sow_status = 'PM Approved'  and implementer = 'C1' THEN sownumber ELSE NULL END) 
        AS pending,
    
    COUNT(DISTINCT CASE WHEN sow_status = 'PM Approved'  and implementer = 'C1' THEN sownumber ELSE NULL END) 
        AS total,
    
    COUNT(DISTINCT CASE WHEN sow_status = 'PM Approved'  and implementer = 'C1' THEN sownumber ELSE NULL END) AS pending
        - COUNT(DISTINCT CASE WHEN name = 'CTN-Approve' and assigned_engineer_my_tasks = 'NotClaimed' and sow_status = 'PM Approved'  and implementer = 'C1' THEN sownumber ELSE NULL END)
        - COUNT(DISTINCT CASE WHEN name = 'CTN-Approve' and assigned_engineer_my_tasks != 'NotClaimed'and sow_status = 'PM Approved'  and implementer = 'C1' THEN sownumber ELSE NULL END)
        AS ongoing
FROM
    v_scope_of_work_combined