SQL Server如何编写查询以将工作分发给员工

SQL Server如何编写查询以将工作分发给员工,sql,asp.net,sql-server,Sql,Asp.net,Sql Server,我有两张桌子。一个表包含员工专业和能力信息。另一个表包含每个专业的每日工作量。我如何编写查询(或查询)以根据每个专业的员工能力分配工作量,无论工作量是大于还是小于能力?工作量为固定值,员工的能力可根据工作量进行调整,但应根据能力比率进行调整。我的目标结果表显示了这种“可调整性” 表1:员工能力 Employee Specialty Daily_Capacity --------------------------------------- Aron Baker DB2

我有两张桌子。一个表包含员工专业和能力信息。另一个表包含每个专业的每日工作量。我如何编写查询(或查询)以根据每个专业的员工能力分配工作量,无论工作量是大于还是小于能力?工作量为固定值,员工的能力可根据工作量进行调整,但应根据能力比率进行调整。我的目标结果表显示了这种“可调整性”

表1:员工能力

Employee Specialty Daily_Capacity --------------------------------------- Aron Baker DB2 10 Aron Baker Oracle 5 Aron Baker SQL Server 10 Justin Ross DB2 20 Justin Ross SQL Server 30 Tom White DB2 5 Tom White Oracle 10 Tom White SQL Server 10 员工专业每日工作能力 --------------------------------------- Aron Baker DB2 10 阿隆·贝克神谕5 Aron Baker SQL Server 10 贾斯汀·罗斯20 Justin Ross SQL Server 30 汤姆怀特5 汤姆·怀特神谕10 Tom White SQL Server 10 表2:日常工作

Specialty Daily_Total ------------------------ DB2 30 Oracle 10 SQL Server 100 专业每日总人数 ------------------------ DB230 甲骨文10 SQL Server 100 我正在寻找一个结果数据表,其中根据员工的日常工作能力,将所有专业人员的每日总工作量适当分配给员工:

Employee Specialty Daily_Work ------------------------------------- Aron Baker DB2 7 Aron Baker Oracle 3 Aron Baker SQL Server 20 Justin Ross DB2 16 Justin Ross SQL Server 60 Tom White DB2 7 Tom White Oracle 7 Tom White SQL Server 20 员工专业日常工作 ------------------------------------- Aron Baker DB2 7 阿隆·贝克神谕3 Aron Baker SQL Server 20 贾斯汀·罗斯16 Justin Ross SQL Server 60 汤姆怀特7 汤姆·怀特神谕7 Tom White SQL Server 20
如果我正确理解你的问题,这是一个简化的anwser。 您聚合第一个表中的数据,然后将其自身连接起来,以获得用于计数的数字

select *,
 e.Daily_Capacity/g.DailySum*d.Daily_Total  from Employee_Capacity e 
 join (select Speciality s, Sum(Daily_Capacity) as DailySum from Employee_Capacity
 group by Speciality) g on g.s = e.Speciality
 join Daily_Work d on d.Speciality = e.Speciality

您必须处理舍入数字,并将类型从int转换为float,以避免丢失小数

如果我正确理解您的问题,这是一个简化的anwser。 您聚合第一个表中的数据,然后将其自身连接起来,以获得用于计数的数字

select *,
 e.Daily_Capacity/g.DailySum*d.Daily_Total  from Employee_Capacity e 
 join (select Speciality s, Sum(Daily_Capacity) as DailySum from Employee_Capacity
 group by Speciality) g on g.s = e.Speciality
 join Daily_Work d on d.Speciality = e.Speciality
您必须处理舍入数字,并将类型从int转换为float,以避免丢失小数

试试这个:

DECLARE @Employee_Capacity TABLE (Employee NVARCHAR(15), Specialty NVARCHAR(15), Daily_Capacity INT)
INSERT INTO @Employee_Capacity VALUES
('Aron Baker',  'DB2',         10),('Aron Baker',  'Oracle',       5),
('Aron Baker',  'SQL Server',  10),('Justin Ross', 'DB2',         20),
('Justin Ross', 'SQL Server',  30),('Tom White',  'DB2',          5),
('Tom White',   'Oracle',      10),('Tom White',   'SQL Server',  10)

DECLARE @Daily_Work TABLE (Specialty NVARCHAR(15), Daily_Total INT)
INSERT INTO @Daily_Work VALUES
('DB2',             30),('Oracle',          10),('SQL Server',     100)

;WITH SOME_TABLE AS ( 
SELECT EC.Employee,DW.*,Daily_Capacity, Daily_Capacity/Divider Divider  FROM @Daily_Work DW 
LEFT JOIN @Employee_Capacity EC 
ON DW.Specialty = EC.Specialty  
LEFT JOIN ( SELECT Specialty Specialty_Ref,MIN(Daily_Capacity) Divider  FROM @Employee_Capacity 
                                                                        GROUP BY Specialty ) B 
ON DW.Specialty = B.Specialty_Ref 
) 

SELECT Employee,ST1.Specialty, (Daily_Total/ST2.Divider)*ST1.Divider Daily_Work 
FROM SOME_TABLE ST1 LEFT JOIN  (SELECT Specialty,SUM(Divider) Divider FROM SOME_TABLE 
GROUP BY Specialty)ST2 ON ST1.Specialty = ST2.Specialty ORDER BY Employee,Specialty
希望有帮助。

试试这个:

DECLARE @Employee_Capacity TABLE (Employee NVARCHAR(15), Specialty NVARCHAR(15), Daily_Capacity INT)
INSERT INTO @Employee_Capacity VALUES
('Aron Baker',  'DB2',         10),('Aron Baker',  'Oracle',       5),
('Aron Baker',  'SQL Server',  10),('Justin Ross', 'DB2',         20),
('Justin Ross', 'SQL Server',  30),('Tom White',  'DB2',          5),
('Tom White',   'Oracle',      10),('Tom White',   'SQL Server',  10)

DECLARE @Daily_Work TABLE (Specialty NVARCHAR(15), Daily_Total INT)
INSERT INTO @Daily_Work VALUES
('DB2',             30),('Oracle',          10),('SQL Server',     100)

;WITH SOME_TABLE AS ( 
SELECT EC.Employee,DW.*,Daily_Capacity, Daily_Capacity/Divider Divider  FROM @Daily_Work DW 
LEFT JOIN @Employee_Capacity EC 
ON DW.Specialty = EC.Specialty  
LEFT JOIN ( SELECT Specialty Specialty_Ref,MIN(Daily_Capacity) Divider  FROM @Employee_Capacity 
                                                                        GROUP BY Specialty ) B 
ON DW.Specialty = B.Specialty_Ref 
) 

SELECT Employee,ST1.Specialty, (Daily_Total/ST2.Divider)*ST1.Divider Daily_Work 
FROM SOME_TABLE ST1 LEFT JOIN  (SELECT Specialty,SUM(Divider) Divider FROM SOME_TABLE 
GROUP BY Specialty)ST2 ON ST1.Specialty = ST2.Specialty ORDER BY Employee,Specialty

希望能有所帮助。

在子句中使用聚合窗口函数来确定每个员工的每个专业相对于其他员工的能力比率,并将该比率乘以
每日总工作量
,以确定
每日工作量

注意:根据实际数据的舍入情况,这可能并不总是可行的

select 
    e.Employee, e.Specialty
  , Employee_Ratio = convert(decimal(9,4),(e.daily_capacity*1.0/sum(e.daily_capacity) over (partition by e.specialty)))
  , Daily_Work = convert(int,round(
      (e.daily_capacity*1.0/sum(e.daily_capacity) over (partition by e.specialty))
      *d.Daily_Total
    ,0))
from employee_capacity e
  inner join daily_work d 
    on e.specialty = d.specialty
rextester演示:

返回:

+-------------+------------+----------------+------------+
|  Employee   | Specialty  | Employee_Ratio | Daily_Work |
+-------------+------------+----------------+------------+
| Aron Baker  | DB2        | 0,2857         |          9 |
| Justin Ross | DB2        | 0,5714         |         17 |
| Tom White   | DB2        | 0,1429         |          4 |
| Tom White   | Oracle     | 0,6667         |          7 |
| Aron Baker  | Oracle     | 0,3333         |          3 |
| Aron Baker  | SQL Server | 0,2000         |         20 |
| Justin Ross | SQL Server | 0,6000         |         60 |
| Tom White   | SQL Server | 0,2000         |         20 |
+-------------+------------+----------------+------------+

将聚合窗口函数与子句一起使用,以确定每个员工在每个专业中相对于其他员工的能力比率,并将该比率乘以
每日总工作量
,以确定
每日工作量

注意:根据实际数据的舍入情况,这可能并不总是可行的

select 
    e.Employee, e.Specialty
  , Employee_Ratio = convert(decimal(9,4),(e.daily_capacity*1.0/sum(e.daily_capacity) over (partition by e.specialty)))
  , Daily_Work = convert(int,round(
      (e.daily_capacity*1.0/sum(e.daily_capacity) over (partition by e.specialty))
      *d.Daily_Total
    ,0))
from employee_capacity e
  inner join daily_work d 
    on e.specialty = d.specialty
rextester演示:

返回:

+-------------+------------+----------------+------------+
|  Employee   | Specialty  | Employee_Ratio | Daily_Work |
+-------------+------------+----------------+------------+
| Aron Baker  | DB2        | 0,2857         |          9 |
| Justin Ross | DB2        | 0,5714         |         17 |
| Tom White   | DB2        | 0,1429         |          4 |
| Tom White   | Oracle     | 0,6667         |          7 |
| Aron Baker  | Oracle     | 0,3333         |          3 |
| Aron Baker  | SQL Server | 0,2000         |         20 |
| Justin Ross | SQL Server | 0,6000         |         60 |
| Tom White   | SQL Server | 0,2000         |         20 |
+-------------+------------+----------------+------------+

它更倾向于算法问题,而不是SQL问题。您在结果集中得出了什么算法公式来获得每日工作?解释您在结果表中计算每日工作列的人感谢您的反馈,Kannan Kandasamy和luisarcher。为了回答Kannan的问题,我自己“手动”使用一个比率或百分比来计算并获得Daily_Work列中的结果值。例如,对于SQL Server,总工作量为100,而员工容量比率为10:30:10。然后,我的“手动”分布是20:60:20(恰好与20+60+20=100完全匹配)。为了回答luisarcher的问题,如果我理解正确,将在employee列中为员工计算Daily_Work列,以便他们有适当的工作量。例如,由于他的日常工作能力,Aron Baker今天得到了7个DB2工作、3个Oracle工作和20个SQL Server工作。当然,我“手动”实现了这个分发。我只是想知道是否有一个或一系列的查询可以得到这个结果。@Yugang想知道,因为所得到的是一个小比例规则,而我没有得到你的值,所以我想知道你的计算结果是什么。这更像是一个算法问题,而不是SQL问题。您在结果集中得出了什么算法公式来获得每日工作?解释您在结果表中计算每日工作列的人感谢您的反馈,Kannan Kandasamy和luisarcher。为了回答Kannan的问题,我自己“手动”使用一个比率或百分比来计算并获得Daily_Work列中的结果值。例如,对于SQL Server,总工作量为100,而员工容量比率为10:30:10。然后,我的“手动”分布是20:60:20(恰好与20+60+20=100完全匹配)。为了回答luisarcher的问题,如果我理解正确,将在employee列中为员工计算Daily_Work列,以便他们有适当的工作量。例如,由于他的日常工作能力,Aron Baker今天得到了7个DB2工作、3个Oracle工作和20个SQL Server工作。当然,我“手动”实现了这个分发。我只是想知道是否有一个或一系列的查询可以得到这个结果。@Yugang想知道,因为所得到的是一个小比例规则,而我没有得到你的值,所以我想知道你的计算结果。谢谢Jan。这对我来说很好!我选择SqlZim的答案作为最佳答案,因为它更全面。谢谢Jan。这对我来说很好!我选择SqlZim的答案作为最佳答案,因为它更全面。我选择SqlZim的答案作为最佳答案,因为它有效,而且也很简单(如Jan的答案),而且回答彻底!我选择SqlZim的答案作为最佳答案,因为它很有效,也很简单(就像Jan的一样),而且回答得很彻底!非常感谢。你的方法有效!我也有过类似的经历,但没有像你一样成功。但我选择SqlZim的答案作为最合适的答案,因为他的答案更简单,而且回答也非常彻底。:)高兴