我有3个表,类别,资源人员和人力资源计划。
我要计算按类别分组的金额
我创建了此SQL查询:
select
CostCategory.CostCategory, sum(isnull(HRPplan.Amount, 0))
from
CostCategory
left join
HRPplan on HRPplan.Month between 1 and 3
and HRPplan.Year = 2019
and HRPplan.IDRPH in (select HumanResource.IDRPH
from HumanResource
where HumanResource.IDCostCategory = CostCategory.IDCostegory)
group by
CostCategory.CostCategory
,它返回一个结果,但是我还有另外两个与人力资源和HPlan完全一样的表,要用它来计算数量,因此,如果我使用上面提到的相同代码,查询性能将不佳。而且我不怎么在SQL中使用函数/过程,因为年和月将作为参数插入。
答案 0 :(得分:1)
为了提高性能,您可以避免使用in子句
select CostCategory.CostCategory, sum(isnull(HRPplan.Amount,0))
from CostCategory
left join HRPplan on HRPplan.Month between 1 and 3 and HRPplan.Year = 2019
LEFT JOIN HumanResource ON HumanResource.IDCostCategory = CostCategory.IDCostegory
and umanResource.IDRPH = HRPplan.IDRPH
group by CostCategory.CostCategory
答案 1 :(得分:1)
在问题中获取DDL和样本数据DML可以更轻松地提供快速解决方案。另外,查询中使用的列与您提供的屏幕截图并不完全相似,因此我将根据提供的屏幕截图提供这些方法。
准备好的DDL和测试数据:
DROP TABLE IF EXISTS CostCategory;
GO
CREATE TABLE CostCategory
(
IDCostCategory INT
,CostCategory VARCHAR(10)
) ON [PRIMARY]
GO
INSERT INTO CostCategory
VALUES
(1, 'A'), (2, 'B'), (3, 'C')
GO
DROP TABLE IF EXISTS HumanResource;
GO
CREATE TABLE HumanResource
(
IDHR INT
,IDCostCategory INT
) ON [PRIMARY]
GO
INSERT INTO HumanResource
VALUES
(1, 1), (2, 2), (3, 2)
GO
DROP TABLE IF EXISTS HRPlan;
GO
CREATE TABLE HRPlan
(
IDHRPlan INT
,IDHR INT
,Amount INT
,Month INT
,Year INT
) ON [PRIMARY]
GO
INSERT INTO HRPlan
VALUES
(1, 1, 10 , 1, 2019)
, (2, 1, 12 , 2, 2019)
, (3, 1, 15 , 2, 2019)
, (4, 2, 50 , 1, 2019)
, (5, 2, 0 , 2, 2019)
, (6, 2, 100 , 3, 2019)
, (4, 3, 40 , 1, 2019)
, (5, 3, 50 , 2, 2019)
, (6, 3, 30 , 3, 2019)
GO
要跟踪性能,您可以将IO和时间统计信息设置为“开”:
SET STATISTICS IO ON;
SET STATISTICS TIME ON;
解决方案1 :使用外部应用(比下面的解决方案2更好的性能)
SELECT CC.CostCategory, ISNULL(OA.Amount, 0)
FROM CostCategory CC
OUTER APPLY (
SELECT Amount = SUM(ISNULL(HP.Amount, 0))
FROM HRPlan HP
WHERE HP.Month BETWEEN 1 AND 3
AND HP.Year = 2019
AND EXISTS (
SELECT 1
FROM HumanResource HR
WHERE HR.IDCostCategory = CC.IDCostCategory
AND HR.IDHR = HP.IDHR
)
) OA;
解决方案2:使用左联接
SELECT CC.CostCategory, ISNULL(SUM(HP.Amount), 0)
FROM CostCategory CC
LEFT JOIN HumanResource HR
ON CC.IDCostCategory = HR.IDCostCategory
LEFT JOIN HRPlan HP
ON HR.IDHR = HP.IDHR
AND HP.Month BETWEEN 1 AND 3
AND HP.Year = 2019
GROUP BY CC.CostCategory;
注意:-您可以考虑在HRPlan表上创建列存储索引,并在其他两个表上创建行存储/列存储索引,这些表涵盖了联接和选定的列,以提高性能。