在问题中获取 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 和时间统计设置为 ON:
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 表上创建列存储索引,并在其他 2 个覆盖连接和选定列的表上创建行存储/列存储索引以获得更好的性能。