Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 请告知我的分组依据的存储过程以及总计的不同标准_Sql Server_Stored Procedures - Fatal编程技术网

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