假设我有以下表格
EmployeeID Salary Date
----------- ---------------- -----------
37 45000.00 2015-03-11
102 36500.00 2015-03-11
103 43000.00 2015-03-11
104 45000.00 2015-03-11
105 40000.00 2015-03-11
37 45000.00 2015-04-11
102 36500.00 2015-04-11
103 43000.00 2015-04-11
104 45000.00 2015-04-11
105 40000.00 2015-04-11
我想要检索"薪酬总和"交叉80000,所以期望的输出是
EmployeeID Salary Date
----------- ---------------- -----------
37 45000.00 2015-03-11
103 43000.00 2015-03-11
104 45000.00 2015-03-11
37 45000.00 2015-04-11
103 43000.00 2015-04-11
104 45000.00 2015-04-11
我是通过以下方式实现的:
INNER加入原始表格和&表变量
DECLARE @tmpAggregatedSalaries TABLE
(
EmployeeID INT,
SumOfSalary DECIMAL(18, 2)
)
INSERT INTO @tmpAggregatedSalaries
SELECT sal.EmployeeID
, SUM(sal.Salary) AS SumOfSalary
FROM Salaries sal
GROUP BY sal.EmployeeID
SELECT sal.*
FROM Salaries sal
INNER JOIN @tmpAggregatedSalaries aggrSal ON sal.EmployeeID = aggrSal.EmployeeID
AND aggrSal.SumOfSalary > 80000
据我所知,存储临时结果以进行处理优先于内联查询,因此我选择"表变量"。请为我推荐更多优化版本。
答案 0 :(得分:1)
一种选择是使用GROUP BY
子查询来识别薪水总和大于80000的所有员工,以过滤掉您不想看到的表中的记录。
SELECT t1.EmployeeID,
t1.Salary,
t1.Date
FROM Salaries t1
INNER JOIN
(
SELECT EmployeeID
FROM Salaries
GROUP BY EmployeeID
HAVING SUM(Salary) > 80000
) t2
ON t1.EmployeeID = t2.EmployeeID
答案 1 :(得分:1)
您还可以使用SUM()
window功能:
CREATE TABLE dbo.Salaries
(
EmployeeID INT
, Salary DECIMAL(10, 2)
, [Date] DATE
, CONSTRAINT PK_Salaries PRIMARY KEY (EmployeeID, [Date])
);
INSERT INTO dbo.Salaries (EmployeeID, Salary, [Date])
VALUES (37, 45000.00, '2015-03-11')
, (102, 36500.00, '2015-03-11')
, (103, 43000.00, '2015-03-11')
, (104, 45000.00, '2015-03-11')
, (105, 40000.00, '2015-03-11')
, (37, 45000.00, '2015-04-11')
, (102, 36500.00, '2015-04-11')
, (103, 43000.00, '2015-04-11')
, (104, 45000.00, '2015-04-11')
, (105, 40000.00, '2015-04-11');
SELECT S.EmployeeID, S.Salary, S.[Date]
FROM (
SELECT EmployeeID, Salary, [Date], SUM(Salary) OVER(PARTITION BY EmployeeID) AS SalarySum
FROM dbo.Salaries
) AS S
WHERE S.SalarySum > 80000;
此查询将计算每位员工的总薪水,之后只会过滤掉总收入少于80000的员工。
结果:
EmployeeID Salary Date
----------- --------------------------------------- ----------
37 45000.00 2015-03-11
37 45000.00 2015-04-11
103 43000.00 2015-03-11
103 43000.00 2015-04-11
104 45000.00 2015-04-11
104 45000.00 2015-03-11
当然,您可以使用Tim建议的内联查询:
SELECT S.EmployeeID, S.Salary, S.[Date]
FROM dbo.Salaries AS S
INNER JOIN (
SELECT EmployeeID, SUM(Salary) AS SalarySum
FROM dbo.Salaries
GROUP BY EmployeeID
) AS T
ON T.EmployeeID = S.EmployeeID
WHERE T.SalarySum > 80000;
对于这样小的结果集,后者似乎通过查看执行计划表现更好。您必须将其与实际数据进行比较,以确定哪个数据表现更好。为两个查询附加计划: