架构信息:
v_ProjectMilestone通过project_id
引用项目里程碑可以是内部的也可以是外部的(milestone.is_external = 1)
里程碑有三个我们关心的日期列(实际,修订或建议)
他们希望能够看到具有每个日期值的里程碑百分比,以及所有这些日期在内部和外部里程碑之间划分,以及每个项目的组合。
with AllMilestones as(
SELECT
(select count(project_id)
from v_ProjectMilestone
where v_ProjectMilestone.project_id=pp.record_id) AS all_milestones,
(select count(project_id)
from v_ProjectMilestone
where v_ProjectMilestone.project_id=pp.record_id
and Actual_date is not null
) AS all_Actual_milestones,
(select count(project_id)
from v_ProjectMilestone
where v_ProjectMilestone.project_id=pp.record_id
and Actual_date is null
and proposed_date is not null
and revised_date is null
) AS all_Proposed_milestones,
(select count(project_id)
from v_ProjectMilestone
where v_ProjectMilestone.project_id=pp.record_id
and Actual_date is null
and revised_date is not null
) AS all_Revised_milestones,
(select count(project_id)
from v_ProjectMilestone
where v_ProjectMilestone.project_id=pp.record_id
and
(Actual_date is not null
or revised_date is not null
or proposed_date is not null)
) AS all_scheduled_milestones,
(select count(project_id)
from v_ProjectMilestone
where v_ProjectMilestone.project_id=pp.record_id
and is_external=1) AS External_milestones,
(select count(project_id)
from v_ProjectMilestone
where v_ProjectMilestone.project_id=pp.record_id
and Actual_date is not null
and is_external=1
) AS External_Actual_milestones,
(select count(project_id)
from v_ProjectMilestone
where v_ProjectMilestone.project_id=pp.record_id
and Actual_date is null
and proposed_date is not null
and revised_date is null
and is_external=1
) AS External_Proposed_milestones,
(select count(project_id)
from v_ProjectMilestone
where v_ProjectMilestone.project_id=pp.record_id
and Actual_date is null
and revised_date is not null
and is_external=1
) AS External_Revised_milestones,
(select count(project_id)
from v_ProjectMilestone
where v_ProjectMilestone.project_id=pp.record_id
and is_external=1
and
(Actual_date is not null
or revised_date is not null
or proposed_date is not null)
) AS External_scheduled_milestones,
(select count(project_id)
from v_ProjectMilestone
where v_ProjectMilestone.project_id=pp.record_id
and is_external=0) AS internal_milestones,
(select count(project_id)
from v_ProjectMilestone
where v_ProjectMilestone.project_id=pp.record_id
and Actual_date is not null
and is_external=0
) AS internal_Actual_milestones,
(select count(project_id)
from v_ProjectMilestone
where v_ProjectMilestone.project_id=pp.record_id
and Actual_date is null
and proposed_date is not null
and revised_date is null
and is_external=0
) AS internal_Proposed_milestones,
(select count(project_id)
from v_ProjectMilestone
where v_ProjectMilestone.project_id=pp.record_id
and Actual_date is null
and revised_date is not null
and is_external=0
) AS internal_Revised_milestones,
(select count(project_id)
from v_ProjectMilestone
where v_ProjectMilestone.project_id=pp.record_id
and is_external=0
and
(Actual_date is not null
or revised_date is not null
or proposed_date is not null)
) AS internal_scheduled_milestones,
project_id
from
project pp
inner join v_ProjectMilestone on v_ProjectMilestone.project_id=pp.record_id
)
select
Cast(Round(
(100.0*AllMilestones.all_actual_milestones)/
nullif(
(1.0*AllMilestones.all_milestones)
,0)
,0)as int) as percent_all_Actual_Milestones,
Cast(Round(
(100.0*AllMilestones.all_Proposed_milestones)/
nullif(
(1.0*AllMilestones.all_milestones)
,0)
,0)as int) as percent_all_Proposed_Milestones,
Cast(Round(
(100.0*AllMilestones.all_Revised_milestones)/
nullif(
(1.0*AllMilestones.all_milestones)
,0)
,0)as int) as percent_all_Revised_Milestones,
Cast(Round(
(100.0*AllMilestones.all_scheduled_milestones)/
nullif(
(1.0*AllMilestones.all_milestones)
,0)
,0)as int) as percent_all_Scheduled_Milestones,
Cast(Round(
(100.0*AllMilestones.External_actual_milestones)/
nullif(
(1.0*AllMilestones.External_milestones)
,0)
,0)as int) as percent_External_Actual_Milestones,
Cast(Round(
(100.0*AllMilestones.External_Proposed_milestones)/
nullif(
(1.0*AllMilestones.External_milestones)
,0)
,0)as int) as percent_External_Proposed_Milestones,
Cast(Round(
(100.0*AllMilestones.External_Revised_milestones)/
nullif(
(1.0*AllMilestones.External_milestones)
,0)
,0)as int) as percent_External_Revised_Milestones,
Cast(Round(
(100.0*AllMilestones.External_scheduled_milestones)/
nullif(
(1.0*AllMilestones.External_milestones)
,0)
,0)as int) as percent_External_Scheduled_Milestones,
Cast(Round(
(100.0*AllMilestones.Internal_actual_milestones)/
nullif(
(1.0*AllMilestones.Internal_milestones)
,0)
,0)as int) as percent_Internal_Actual_Milestones,
Cast(Round(
(100.0*AllMilestones.Internal_Proposed_milestones)/
nullif(
(1.0*AllMilestones.Internal_milestones)
,0)
,0)as int) as percent_Internal_Proposed_Milestones,
Cast(Round(
(100.0*AllMilestones.Internal_Revised_milestones)/
nullif(
(1.0*AllMilestones.Internal_milestones)
,0)
,0)as int) as percent_Internal_Revised_Milestones,
Cast(Round(
(100.0*AllMilestones.Internal_scheduled_milestones)/
nullif(
(1.0*AllMilestones.Internal_milestones)
,0)
,0)as int) as percent_Internal_Scheduled_Milestones
,project.*,
AllMilestones.*
from AllMilestones inner join project on project.record_id = AllMilestones.project_id
答案 0 :(得分:3)
是的,您可以使用CASE表达式替换所有子查询,该表达式检查每个子查询的WHERE子句中的条件。
例如,您的前两个子查询将替换为:
count(project_id) AS all_milestones,
SUM(CASE WHEN Actual_date is not null THEN 1 ELSE 0 END) AS all_Actual_milestones,
等等。
至于它是否会有更好的表现,除了尝试之外,我无法确定除此之外。
答案 1 :(得分:2)
您的查询非常复杂;你必须一遍又一遍地读同一张桌子。你需要的是条件聚合。我移动NULLIF
以避免将零除以WITH
子句,以便不必在每一行中重复它。
with allmilestones as
( select
project_id,
nullif(count(*),0) as all_milestones,
count(case when
actual_date is not null
then 1 end) as all_actual_milestones,
count(case when
actual_date is null
and proposed_date is not null
and revised_date is null
then 1 end) as all_proposed_milestones,
count(case when
actual_date is null
and revised_date is not null
then 1 end) as all_revised_milestones
,count(case when
(Actual_date is not null
or revised_date is not null
or proposed_date is not null)
then 1 end) as all_scheduled_milestones,
count(case when
is_external=1
then 1 end) as external_milestones,
count(case when
is_external=1 and
actual_date is not null
then 1 end) as external_actual_milestones,
count(case when
is_external=1 and
actual_date is null
and proposed_date is not null
and revised_date is null
then 1 end) as external_proposed_milestones,
count(case when
is_external=1 and
actual_date is null
and revised_date is not null
then 1 end) as external_revised_milestones
,count(case when
is_external=1 and
(Actual_date is not null
or revised_date is not null
or proposed_date is not null)
then 1 end) as external_scheduled_milestones,
count(case when
is_external=0
then 1 end) as internal_milestones,
count(case when
is_external=0 and
actual_date is not null
then 1 end) as internal_actual_milestones,
count(case when
is_external=0 and
actual_date is null
and proposed_date is not null
and revised_date is null
then 1 end) as internal_proposed_milestones,
count(case when
is_external=0 and
actual_date is null
and revised_date is not null
then 1 end) as internal_revised_milestones
,count(case when
is_external=0 and
(Actual_date is not null
or revised_date is not null
or proposed_date is not null)
then 1 end) as internal_scheduled_milestones
from v_projectmilestone
group by project_id
)
select
project_id,
cast( round(100.0 * all_actual_milestones / all_milestones, 0) as int) as percent_all_actual_milestones,
cast( round(100.0 * all_proposed_milestones / all_milestones, 0) as int) as percent_all_proposed_milestones,
cast( round(100.0 * all_revised_milestones / all_milestones, 0) as int) as percent_all_revised_milestones,
cast( round(100.0 * all_scheduled_milestones / all_milestones, 0) as int) as percent_all_scheduled_milestones ,
cast( round(100.0 * external_actual_milestones / nullif(external_milestones,0), 0) as int) as percent_external_actual_milestones,
cast( round(100.0 * external_proposed_milestones / nullif(external_milestones,0), 0) as int) as percent_external_proposed_milestones,
cast( round(100.0 * external_revised_milestones / nullif(external_milestones,0), 0) as int) as percent_external_revised_milestones,
cast( round(100.0 * external_scheduled_milestones / nullif(external_milestones,0), 0) as int) as percent_external_scheduled_milestones,
cast( round(100.0 * internal_actual_milestones / nullif(internal_milestones,0), 0) as int) as percent_internal_actual_milestones,
cast( round(100.0 * internal_proposed_milestones / nullif(internal_milestones,0), 0) as int) as percent_internal_proposed_milestones,
cast( round(100.0 * internal_revised_milestones / nullif(internal_milestones,0), 0) as int) as percent_internal_revised_milestones,
cast( round(100.0 * internal_scheduled_milestones / nullif(internal_milestones,0), 0) as int) as percent_internal_scheduled_milestones
from allmilestones;
这应该尽可能快,因为你只读了一次表。我希望我说得对,你想要每个项目一个结果行。