【问题标题】:Calculating Percentages with SUM and Group by使用 SUM 和 Group by 计算百分比
【发布时间】:2016-07-02 11:15:36
【问题描述】:

我正在尝试根据一些设定的标准创建一个随着时间的推移计算。它如下。

加班时间在超过 8 小时的任何一天发布,但员工必须首先达到 40 小时的总时数,并且从一周的第一天开始计算。加班时间是根据在工作成本代码中占SUM 总数的百分比计算的。

首先,您必须找出每个员工 ID 在整个一周内工作的每个成本代码的百分比。请参阅下面的示例

然后,在超过 8 小时的每一天,您都花时间在该代码上,并将其乘以计算出的百分比。在一周结束时,如果一周超过 40 小时,则正常工作时间必须总计 40 小时。见下例

CREATE TABLE [Totals](
    [Day] nvarchar (10) null,
    [EmployeeID] [nvarchar](100) NULL,
    [CostCode] [nvarchar](100) NULL,
    [TotalTime] [real] NULL,)

INSERT  Into Totals (day,employeeid, CostCode, TotalTime) VALUES
('1','1234','1', 2),
('1','1234','2', 7.5),
('2','1234','1', 1.5),
('2','1234','2', 8),
('3','1234','1', 1),
('3','1234','2', 6),
('4','1234','1', 2),
('4','1234','2', 8),
('5','1234','1', 2),
('5','1234','2', 8),
('1','4567','1', 2),
('1','4567','2', 8.5),
('2','4567','1', 1.5), 
('2','4567','2', 7.6),
('3','4567','1', 1),
('3','4567','2', 5),
('4','4567','1', 2),
('4','4567','2', 8),
('5','4567','1', 2),
('5','4567','2', 8)

要获得每项成本的百分比,它是每周每项成本的总时间 / 整周总时间的总和

   SELECT employeeid,CostCode,SUM(totaltime) As TotalTime ,
   ROUND(SUM(Totaltime) / (select SUM(TotalTime) from Totals where employeeid = '1234') * 100,0) as Percentage
    from Totals WHERE EmployeeID = '1234' group by EmployeeID, CostCode

按成本计算的本周百分比 = 18% 的人使用成本 1,82% 的人使用成本 2

我想获取一周的百分比结果并计算查询中每天的总时间

结果示例第 1 天:对于 EmployeeID 1234

Day CostCode RegTime OverTime 
 1     1        1.73     .27      
 1     2        6.27    1.23

【问题讨论】:

  • 能否更新表格格式的预期结果
  • 我没有看到任何可以说明这些时间的“日期”的信息。
  • 你是怎么达到 22.666 % 的? (Emp 1234 - CostCode:1, TotalTime:8.5 & CostCode:2, TotalTime:37.5) rgt?
  • 您必须提供用于计算 22.666% 的逻辑此时您的问题完全不清楚。用户 1234 在成本 1 上工作了 2 小时,在成本 2 上工作了 7.5 小时。这给您 9.5 小时,这意味着员工每天工作 1.5 小时超过 8 小时:(9.5-8)/8 = 0.1875!
  • BrianMichaels,请检查您的数据,因为工作不正确。例如Person1234 在 1 上工作了 8.5 小时,在 2 上工作了 37.5 小时,分别为 18.5% 和 81.5%。还要简化拼图的措辞。例如这句话中有 2 个独立的逻辑位“加班时间在超过 8 小时的任何一天发布,但员工必须首先达到 40 小时,并且计算从一周内的第一天开始计算。”你也有第 1 天代码 1 的 2 小时达到 1.2 和 0.34 当天的另一个 0.46 去哪儿了?你的例子都没有加起来。

标签: sql sql-server sql-server-2012


【解决方案1】:

编辑后我得到你的结果,试试这个:

select calc.*
--select [day], CostCode, EmployeeID
--, CPr * DayEmpRT RegTime_old
, TotalTime - CPr * DayEmpOT RegTime
, CPr * DayEmpOT OverTime
from ( 
  select Agr.*
  --, round(EmpC1T / EmpT, 2) C1Pr
  --, round(1 - (EmpC1T / EmpT), 2) C2Pr
  , round(EmpCT / EmpT, 2) CPr
  , case when DayEmpT > 8 then 8 else DayEmpT end DayEmpRT
  , case when DayEmpT > 8 then DayEmpT - 8 else 0 end DayEmpOT
  from (
    select Totals.*
    , SUM(TotalTime) over (partition by EmployeeID, [day]) DayEmpT
    --, SUM(case when CostCode = 1 then TotalTime end) over (partition by EmployeeID) EmpC1T
    , SUM(TotalTime) over (partition by EmployeeID, CostCode) EmpCT
    , SUM(TotalTime) over (partition by EmployeeID) EmpT
    from Totals
    WHERE EmployeeID = '1234' ) Agr ) calc
order by 1,2,3

这是最简单的计算方法:

select calc.*
, TotalTime * pr4R RegTime
, TotalTime * pr4O OverTime
from(
  select Agr.*
  , case when EmpT > 40 then round(40/EmpT, 2) else 1 end pr4R
  , case when EmpT > 40 then round(1 - 40/EmpT, 2) else 1 end pr4O
  from (
    select Totals.*
    , SUM(TotalTime) over (partition by EmployeeID) EmpT
    from Totals
    WHERE EmployeeID = '1234' ) Agr ) calc

但要注意第 3 天,因为只有 7 小时。 第一个查询分别计算天数和第 3 天。 第二个查询规模所有时间。 它可能是另一个,它计算所有 emp 行,但分别缩放 RegTime 和 OverTime,但在没有 8h 的日子除外,并将其从 OverTime 增加到 8h。

【讨论】:

    【解决方案2】:

    这应该可以帮助您入门...

    -- % based on hours worked for each code on a DAILY basis (The original 21% in the question was based on this)
    SELECT
    T.EmployeeId,
    T.Day,
    T.CostCode,
    T.TotalTime,
    CAST(100.0 * T.TotalTime / X.DailyHours AS DECIMAL(10,2)) AS PercentageWorked
    FROM #Totals T
    INNER JOIN (
        SELECT
        EmployeeId,
        Day,
        SUM(TotalTime) AS DailyHours
        FROM #Totals
        GROUP BY EmployeeId, Day
    ) X ON X.EmployeeId = T.EmployeeId AND X.Day = T.Day
    
    
    -- % based on hours worked for each code on a WEEKLY basis (The revised question)
    SELECT
    T.EmployeeId,
    T.CostCode,
    SUM(T.TotalTime) AS TotalTime,
    CAST(100.0 * SUM(T.TotalTime) / X.WeeklyHours AS DECIMAL(10,2)) AS PercentageWorked
    FROM #Totals T
    INNER JOIN (
        SELECT
        EmployeeId,
        SUM(TotalTime) AS WeeklyHours
        FROM #Totals
        GROUP BY EmployeeId
    ) X ON X.EmployeeId = T.EmployeeId 
    GROUP BY 
    T.EmployeeId,
    T.CostCode, 
    X.WeeklyHours
    

    【讨论】:

      猜你喜欢
      • 2013-05-31
      • 2011-09-06
      • 1970-01-01
      • 1970-01-01
      • 2019-05-08
      • 2021-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多