根据SQL Server中的总小时数计算工资

问题描述 投票:0回答:2

如何根据总工时计算工资?我有两个表和一个计算每天总小时数的查询。

officer_timelogs

employee_id      record_time             Day      type
--------------------------------------------------------
125         2018-02-27 18:03:31.000    Tuesday     1
125         2018-02-27 07:54:03.000    Tuesday     0

officer_rate

employee_id     designation      salary
125             programmer       100 (hour)

SQL查询:

select
    employee_id, 
    [Date], DATENAME(WEEKDAY, date)as [Day], 
    [Hours] = right(concat('00', diff / 3600), 2) + ' : ' + right(concat('00', diff % 3600 / 60), 2) + ' : ' + right(concat('00', diff % 60), 2)
from (
    select
        employee_id, 
        [date] = cast(record_time as date),
        diff = datediff(ss, min(iif(type = 0, record_time, null)), max(iif(type = 1, record_time, null)))
    from
        officer_timelogs
    where employee_id = '125'
    group by employee_id, cast(record_time as date)
) t
order by date desc

输出:

employee_id   Date       Day           Hours
    125    2018-03-02   Friday      09 : 00 : 00
    125    2018-03-01   Thursday    10 : 10 : 49
    125    2018-02-28   Wednesday   10 : 14 : 11
    125    2018-02-27   Tuesday     10 : 09 : 28
    125    2018-02-26   Monday      10 : 13 : 34

期望的输出(我想要检索这样的数据)

employee_id   Date       Day           Hours        Salary
    125    2018-03-02   Friday      09 : 00 : 00     900
sql-server datetime
2个回答
1
投票

我认为你做过最复杂的部分。

由于你已经有了工作时间,你只需要乘以工资,如下所示:

select
    t.employee_id, 
    [Date], DATENAME(WEEKDAY, date)as [Day], 
    [Hours] = right(concat('00', diff / 3600), 2) + ' : ' + right(concat('00', diff % 3600 / 60), 2) + ' : ' + right(concat('00', diff % 60), 2),
    diff * r.salary / 3600 AS Salary

from (
    select
        employee_id, 
        [date] = cast(record_time as date),
        diff = datediff(ss, min(iif(type = 0, record_time, null)), max(iif(type = 1, record_time, null)))
    from
        officer_timelogs
    where employee_id = '125'
    group by employee_id, cast(record_time as date)
) t
INNER JOIN officer_rate r ON t.employee_id = r.employee_id
order by date desc

你可以在这个SQL Fiddle上查看它。

Edit: Code and demo updated with OT rate:

在这种情况下,您需要检查是否应该使用OT。如果该人工作8小时或更短时间,我们会考虑常规费率。 8小时的差异是通过考虑20%的小时工资来计算的:

select
    t.employee_id, 
    [Date], DATENAME(WEEKDAY, date)as [Day], 
    [Hours] = right(concat('00', diff / 3600), 2) + ' : ' + right(concat('00', diff % 3600 / 60), 2) + ' : ' + right(concat('00', diff % 60), 2),
    CAST(
    CASE WHEN diff <= 3600 * 8
        THEN diff * r.salary / 3600
        ELSE 
            (3600 * 8 * r.salary / 3600) -- salary x 8h / work
            + (diff - (3600 * 8)) * r.salary * 0.2 /3600 -- OT work
        END AS decimal(10, 2)) AS Salary
from (
    select
        employee_id, 
        [date] = cast(record_time as date),
        diff = datediff(ss, min(iif(type = 0, record_time, null)), max(iif(type = 1, record_time, null)))
    from
        officer_timelogs
    where employee_id = '125'
    group by employee_id, cast(record_time as date)
) t
INNER JOIN officer_rate r ON t.employee_id = r.employee_id
order by date desc;

Demo updated here


0
投票

也许这个。我敢打赌你需要将小时数转换为小数,这样1小时30分钟就能达到1.5

select
    employee_id, 
    [Date], DATENAME(WEEKDAY, date)as [Day], 
    [Hours] = right(concat('00', diff / 3600), 2) + ' : ' + right(concat('00', diff % 3600 / 60), 2) + ' : ' + right(concat('00', diff % 60), 2),
    Salary = <However you need to get hour(s) as a decimal> * tl2.salary
from (
    select
        employee_id, 
        [date] = cast(record_time as date),
        diff = datediff(ss, min(iif(type = 0, record_time, null)), max(iif(type = 1, record_time, null)))
    from
        officer_timelogs
    where employee_id = '125'
    group by employee_id, cast(record_time as date)
) t
INNER JOIN officer_rate tl2 ON tl2.employee_id=t.employee_id
order by date desc
© www.soinside.com 2019 - 2024. All rights reserved.