我有这样的查询(请忽略其中的一些错误,因为查询已被更改并简化以隐藏一些信息):
SELECT
-- Some columns
(case when Benefit.Type = 0 then Benefit.HS end) as HSF,
(case when Benefit.Type = 1 then Benefit.HS end) as HSR,
(case when Benefit.Type = 0 then Benefit.VS end) as VSF,
(case when Benefit.Type = 1 then Benefit.VS end) as VSR,
(case when Benefit.Type = 0 then Benefit.SS end) as SSF,
(case when Benefit.Type = 1 then Benefit.SS end) as SSR,
(case when Benefit.Type = 0 then Benefit.HS + Benefit.VS + Benefit.SS end) as BF,
(case when Benefit.Type = 1 then Benefit.HS + Benefit.VS + Benefit.SS end) as BR
FROM
Project
left join BC on BC.Project_Id = Project.Id
left join (select Seq, BC.Type,
SUM(case PT.Name
when 'Ch' then
case Benefit.Analysis
when 2 then IBenefit.VHS * 12
when 1 then IBenefit.VHS end
else IBenefit.VHS end) HS,
SUM(case PT.Name
when 'Ch' then
case Benefit.Analysis
when 2 then IBenefit.VVS * 12
when 1 then IBenefit.VVS end
else IBenefit.VVS end) VS,
SUM(case PT.Name
when 'Ch' then
case Benefit.Analysis
when 2 then IBenefit.VSS * 12
when 1 then IBenefit.VSS end
else IBenefit.VSS end) SS
from Project
left join BC on BC.Project_Id = Project.Id
left join Benefit on Benefit.BC_Id = BC.Id
left join IBenefit on IBenefit.Benefit_Id = Benefit.Id
group by Project.Seq, BC.Type) as Benefit on Benefit.Seq = Project.Seq
-- Some more JOINs like this
基本上这个查询从多个关系(在Project,BC,Benefit和IBenefit之间)获取数据并在子查询中进行汇总,因此计算不必重复(我的意思是select语句中的代码) (case when Benefit.Type = ....
)。
我想知道这是否真的是最好的方法,或者我是否应该选择所有必要的信息(甚至为同一个项目创建多个行)并使用外部查询(SELECT ... FROM (SELECT ...) AS QUERY
)对它们进行分组。
不确定我的描述是否清楚,所以如果您有任何问题请随时问我。
预期产出:
+---------+---------+--------+---------+--------+--------+---------+--------+---------+ | Project | HSF | HSR | VSF | VSR | SSF | SSR | BF | BR | +---------+---------+--------+---------+--------+--------+---------+--------+---------+ | A | 3432 | 324234 | 876898 | 987987 | 987987 | 9879879 | 987987 | 9879879 | | B | 8765865 | 675875 | 9758975 | 9859 | 85 | 985985 | 985985 | 985 | | C | 87687 | 7687 | 687687 | 876876 | 876876 | 876087 | 987986 | 9869 | +---------+---------+--------+---------+--------+--------+---------+--------+---------+
但没有计算/聚合的数据是这样的:
+---------+--------+-----------+-----------+-----------+-----------------+-------------+-------------+-------------+ | Project | BCType | BenefitHS | BenefitVS | BenefitSS | BenefitAnalysis | IBenefitVHS | IBenefitVSS | IBenefitVVS | +---------+--------+-----------+-----------+-----------+-----------------+-------------+-------------+-------------+ | A | 0 | 3 | 2 | 6 | 5 | 5 | 7 | 6 | | A | 1 | 3 | 7 | 7 | 76 | 68 | 8 | 6 | | B | 0 | 3 | 7 | 7 | 8 | 7 | 9 | 3 | | C | 0 | 2 | 6 | 98 | 5 | 97 | 6 | 5 | | C | 1 | 6 | 8 | 5 | 0 | 5 | 9 | 7 | +---------+--------+-----------+-----------+-----------+-----------------+-------------+-------------+-------------+
这些是假值,只是为了显示摘要的想法。
如果我不使用此子查询,我的主查询将是这样的:
SELECT
-- Some columns
(case when Benefit.Type = 0 then
SUM(case PT.Name
when 'Ch' then
case Benefit.Analysis
when 2 then IBenefit.VHS * 12
when 1 then IBenefit.VHS end
else IBenefit.VHS end) end) as HSF,
(case when Benefit.Type = 1 then
SUM(case PT.Name
when 'Ch' then
case Benefit.Analysis
when 2 then IBenefit.VHS * 12
when 1 then IBenefit.VHS end
else IBenefit.VHS end) end) as HSR,
(case when Benefit.Type = 0 then
SUM(case PT.Name
when 'Ch' then
case Benefit.Analysis
when 2 then IBenefit.VVS * 12
when 1 then IBenefit.VVS end
else IBenefit.VVS end) end) as VSF,
(case when Benefit.Type = 1 then
SUM(case PT.Name
when 'Ch' then
case Benefit.Analysis
when 2 then IBenefit.VVS * 12
when 1 then IBenefit.VVS end
else IBenefit.VVS end) end) as VSR,
(case when Benefit.Type = 0 then
SUM(case PT.Name
when 'Ch' then
case Benefit.Analysis
when 2 then IBenefit.VSS * 12
when 1 then IBenefit.VSS end
else IBenefit.VSS end) end) as SSF,
(case when Benefit.Type = 1 then
SUM(case PT.Name
when 'Ch' then
case Benefit.Analysis
when 2 then IBenefit.VSS * 12
when 1 then IBenefit.VSS end
else IBenefit.VSS end) end) as SSR,
(case when Benefit.Type = 0 then Benefit.HS + SUM(case PT.Name
when 'Ch' then
case Benefit.Analysis
when 2 then IBenefit.VVS * 12
when 1 then IBenefit.VVS end
else IBenefit.VVS end) + SUM(case PT.Name
when 'Ch' then
case Benefit.Analysis
when 2 then IBenefit.VSS * 12
when 1 then IBenefit.VSS end
else IBenefit.VSS end) end) as BF,
(case when Benefit.Type = 1 then Benefit.HS + SUM(case PT.Name
when 'Ch' then
case Benefit.Analysis
when 2 then IBenefit.VVS * 12
when 1 then IBenefit.VVS end
else IBenefit.VVS end) + SUM(case PT.Name
when 'Ch' then
case Benefit.Analysis
when 2 then IBenefit.VSS * 12
when 1 then IBenefit.VSS end
else IBenefit.VSS end) end) as BR
FROM
Project
left join BC on BC.Project_Id = Project.Id
left join Benefit on Benefit.BC_Id = BC.Id
left join IBenefit on IBenefit.Benefit_Id = Benefit.Id
-- Some more JOINs like this
答案 0 :(得分:0)
我注意到的第一件事是,你在子查询和主查询中有类似的表。因此,您可以在主查询本身中执行计算/聚合部分,而不是使用子查询。它将减少sql server查询优化器必须访问相同表以获取数据的次数。此外,它将使您的代码更易读,更易于理解。
注意:这只是基于观察,最好的方法将取决于预期的结果和预期的表现。