系
+-------+------------+
| EmpId | DepId|
+-------+------------+
| 1 | IT |
| 2 | admin |
| 3 | IT |
| 4 | IT |
| 5 | admin |
+-------+------------+
出席率
+-------+--------+
| EmpId | Status |
+-------+--------+
| 1 | P |
| 2 | P |
| 3 | P |
| 4 | A |
| 5 | P |
+-------+--------+
期望输出:
+-------+------------+--------------+
| DepId | TotalCount | PresentCount |
+-------+------------+--------------+
| Admin | 2 | 2 |
| IT | 3 | 2 |
+-------+------------+--------------+
我的查询:
SELECT DepId,
COUNT(att.empid) total,
sum(CASE WHEN status = 'P' THEN 1 ELSE 0 END) presetCount
FROM attendance att
INNER JOIN departments dep ON att.empid=dep.empid
GROUP BY DepId
这可以进一步优化吗?如果是的话怎么样?
答案 0 :(得分:0)
IF OBJECT_ID('dbo.departments', 'U') IS NOT NULL
DROP TABLE dbo.departments
GO
IF OBJECT_ID('dbo.attendance', 'U') IS NOT NULL
DROP TABLE dbo.attendance
GO
CREATE TABLE dbo.departments (EmpId INT PRIMARY KEY, DepId VARCHAR(10))
GO
INSERT INTO dbo.departments
VALUES (1, 'IT'), (2, 'admin'), (3, 'IT'), (4, 'IT '), (5, 'admin')
GO
CREATE TABLE dbo.attendance (EmpId INT PRIMARY KEY, [Status] CHAR(1))
GO
INSERT INTO dbo.attendance
VALUES (1, 'P'), (2, 'P'), (3, 'P'), (4, 'A'), (5, 'P')
GO
CREATE NONCLUSTERED INDEX ix ON dbo.departments (DepId)
GO
SELECT
DepId
, COUNT_BIG(1) AS total
, COUNT_BIG(att.EmpId) AS presetCount
FROM departments dep
LEFT JOIN attendance att ON att.empid = dep.EmpId AND att.[status] = 'P'
GROUP BY DepId
我的执行计划:
您的执行计划:
输出 -
DepId total presetCount
---------- -------------------- -------------
admin 2 2
IT 3 2
答案 1 :(得分:0)
因为您正在比较效果,我建议您尝试APPLY
:
SELECT DepId, a.total, a.presentCount
FROM departments dep OUTER APPLY
(SELECT COUNT(*) as total,
SUM(CASE WHEN status = 'P' THEN 1 ELSE 0 END) as presentCount
FROM attendance att
WHERE att.empid = dep.empid
) a;
然后,请确保您在attendance(empid, status)
上有索引。
我并不是说这更快(取决于数据的大小和其他考虑因素)。但值得检查,因为它绕过外部聚合。
注意:检查小数据集的性能通常是没有意义的。执行计划和性能特征在很大程度上取决于数据的大小。