Sql server 请告知我的分组依据的存储过程以及总计的不同标准
我已经回答了以下一个面试问题 有两个表(员工和部门)。Sql server 请告知我的分组依据的存储过程以及总计的不同标准,sql-server,stored-procedures,Sql Server,Stored Procedures,我已经回答了以下一个面试问题 有两个表(员工和部门)。 显示报告人数(计数)和总工资,其中IT部门工资从250到500,销售部门工资从250到1000,营销部门工资从250到1500 下面是预期结果示例 Marketing 0 0.00 Information Technology 1 250.00 Sales 2 1200.00 员工表 EmpID EmpName DeptID Salary
显示报告人数(计数)和总工资,其中IT部门工资从250到500,销售部门工资从250到1000,营销部门工资从250到1500 下面是预期结果示例
Marketing 0 0.00
Information Technology 1 250.00
Sales 2 1200.00
员工表
EmpID EmpName DeptID Salary
1 Mike 1 1000.00
2 Paul 1 1500.00
3 John 1 2000.00
4 Joe 2 500.00
5 Kim 3 2000.00
6 Lim 3 2500.00
7 Sam 2 700.00
8 Mario 1 250.00
SELECT d.DeptName, ISNULL(e.NoEmp,0) AS NoEmp, ISNULL(SumSalary,0) AS SumSalary
FROM [dbo].[Department] AS d
LEFT JOIN (
SELECT DeptID, COUNT(EmpID) As NoEmp, SUM (Salary) AS SumSalary
FROM [dbo].[Employee]
WHERE Salary BETWEEN 250 AND CASE WHEN DeptID = 1 THEN 500
WHEN DeptID = 2 THEN 1000
WHEN DeptID = 3 THEN 1500
END
GROUP BY DeptID) AS e ON d.DeptID = e.DeptID
WHERE d.DeptID IN(1,2,3)
部门表
DeptID DeptCode DeptName
1 IT Information Technology
2 ST Sales
3 MT Marketing
我的答覆是:
ALTER PROCEDURE [dbo].[TheseAndThat]
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
SELECT dd.DeptName, ISNULL(TT.c,0) AS StaffCount , ISNULL(TT.s,0) AS TotalSalary FROM [dbo].[Department] dd
LEFT JOIN
(
SELECT d.DeptCode AS dcode, COUNT(*) as c, SUM(e.Salary) as s FROM [dbo].[Employee] e
JOIN [dbo].[Department] d
ON e.DeptID = d.DeptID
WHERE e.Salary between 250 and 500 AND d.DeptID = 1
GROUP BY e.DeptID, d.DeptCode
UNION
SELECT d.DeptCode AS dcode, COUNT(*) as c, SUM(e.Salary) as s FROM [dbo].[Employee] e
JOIN [dbo].[Department] d
ON e.DeptID = d.DeptID
WHERE e.Salary between 250 and 1000 AND d.DeptID = 2
GROUP BY e.DeptID, d.DeptCode
UNION
SELECT d.DeptCode AS dcode, COUNT(*) as c, SUM(e.Salary) as s FROM [dbo].[Employee] e
JOIN [dbo].[Department] d
ON e.DeptID = d.DeptID
WHERE e.Salary between 250 and 1500 AND d.DeptID = 3
GROUP BY e.DeptID, d.DeptCode
) TT
ON dd.DeptCode = TT.dcode
ORDER BY TT.c
END
我不确定我的答案是否正确。然而,结果似乎是好的。
请告知。如果我是你,我将执行此查询(仅1次扫描员工表)
首先,设置临时表的代码:
declare @employees table
(
EmpID int,
EmpName varchar(100),
DeptID int,
Salary decimal
)
declare @departament table
(
DeptID int,
DeptCode char(2),
DeptName varchar(100)
)
insert into @employees values (1,'Mike',1,1000.00)
insert into @employees values (2,'Paul',1,1500.00)
insert into @employees values (3,'John',1,2000.00)
insert into @employees values (4,'Joe',2,500.00)
insert into @employees values (5,'Kim',3,2000.00)
insert into @employees values (6,'Lim',3,2500.00)
insert into @employees values (7,'Sam',2,700.00)
insert into @employees values (8,'Mario',1,250.00)
insert into @departament values (1, 'IT', 'Information Technology')
insert into @departament values (2, 'ST', 'Sales')
insert into @departament values (3, 'MT', 'Marketing')
现在,报告:
select DeptName, COALESCE(d2.DeptID, 0), COALESCE(Salaries,0) from @departament d2
left join
(
select COUNT(*) as DeptID, SUM(Salary) as Salaries from @departament d
inner join @employees e on d.DeptID = e.DeptID
where
(d.DeptID = 1 and e.Salary between 250 and 500)
or
(d.DeptID = 2 and e.Salary between 250 and 1000)
or
(d.DeptID = 3 and e.Salary between 250 and 1500)
group by d.DeptID) as sums on sums.DeptID = d2.DeptID
备选方案(使用与@GustavoF answer相同的临时表):
输出:
DeptName EmployeeCount TotalSalary
--------------------------- ------------- -------------
Marketing 0 0
Information Technology 1 250
Sales 2 1200
这更适合于对OP解决方案进行评论:总体而言,这不是一个不合理的尝试,但您应该使用
UNION ALL
而不是UNION
,因为您希望包含所有结果(请参见:)还有,您为什么要在子查询中加入[Department]
表,当您没有从该表中检索到任何信息时?嗨@HoneyBadger,谢谢您的建议。我应该为下一个类似的问题发布codereview。嗨@Alex,谢谢你的推荐。你问的每一个问题都是我学到的新的一课,因为我对SQL查询非常陌生。@Mike,不客气!谢谢你@Alex的回答。我从你的提问中学到了很多东西。谢谢你@Gustavo F的回答。我从你的提问中学到了很多东西。谢谢@Edward N的回答。我也从你的提问中学到了很多东西。
DeptName EmployeeCount TotalSalary
--------------------------- ------------- -------------
Marketing 0 0
Information Technology 1 250
Sales 2 1200