简体   繁体   English

如何在SQL中进行大小写,如if elseif语句

[英]How to do case in sql like if elseif statement

If you see here 如果你在这里看到

CREATE TABLE timesheet
    ([username] varchar(31), [local_date] datetime, [hours] numeric, [wday] varchar(31))
;

INSERT INTO timesheet
    ([username], [local_date], [hours],[wday])
VALUES
    ('emilioh@thinkpowersolutions.com', '1915-05-24 19:00:00', 3.75,'Sun'),
    ('emilioh@thinkpowersolutions.com', '1915-05-25 19:00:00', 11,'Mon'),
    ('emilioh@thinkpowersolutions.com', '1915-05-26 19:00:00', 10.25,'Tue'),
    ('emilioh@thinkpowersolutions.com', '1915-05-27 19:00:00', 13,'Wed'),
    ('emilioh@thinkpowersolutions.com', '1915-05-28 19:00:00', 13,'Thu'),
    ('emilioh@thinkpowersolutions.com', '1915-05-29 19:00:00', 14,'Fri'),
    ('emilioh@thinkpowersolutions.com', '1915-05-30 19:00:00', 9,'Sat'),
    ('emilioh@thinkpowersolutions.com', '1915-05-31 19:00:00', 12,'Sun'),
    ('emilioh@thinkpowersolutions.com', '1915-06-01 19:00:00', 12.5,'Mon')
;

select 
    username
    , datepart(week,local_date)  as Week
    , sum(hours) total
    , case when sum(hours) <= 40 then sum(hours) else 40 end as Regulartime
    , case when sum(hours)  > 40 then sum(hours) - 40 else 0 end as Overtime
from timesheet 
group by username, datepart(week, local_date);

SQL Fiddle SQL小提琴

I have a timesheet table with hours and days. 我有一个时间表,上面有小时和几天。 I need to calculate regular time. 我需要计算固定时间。 Regular time should be only weekday hours and should be <=40. 常规时间应仅为工作日时间,且应小于等于40。 If its weekend or >40 then its overtime. 如果周末或> 40,则加班。 How do I do it in SQL? 如何在SQL中执行此操作?

    CREATE TABLE #timesheet
        ([username] varchar(31), [local_date] datetime, [hours] numeric(6,2), [wday] varchar(31))

    INSERT INTO #timesheet
        ([username], [local_date], [hours],[wday])
    VALUES
        ('emilioh@thinkpowersolutions.com', '2015-05-24 19:00:00', 3.75 ,'Sun'),
        ('emilioh@thinkpowersolutions.com', '2015-05-25 19:00:00', 11   ,'Mon'),
        ('emilioh@thinkpowersolutions.com', '2015-05-26 19:00:00', 10.25,'Tue'),
        ('emilioh@thinkpowersolutions.com', '2015-05-27 19:00:00', 13   ,'Wed'),
        ('emilioh@thinkpowersolutions.com', '2015-05-28 19:00:00', 13   ,'Thu'),
        ('emilioh@thinkpowersolutions.com', '2015-05-29 19:00:00', 14   ,'Fri'),
        ('emilioh@thinkpowersolutions.com', '2015-05-30 19:00:00', 9    ,'Sat'),    
        ('emilioh@thinkpowersolutions.com', '2015-05-31 19:00:00', 12   ,'Sun'),
        ('emilioh@thinkpowersolutions.com', '2015-06-01 19:00:00', 12.5 ,'Mon')

    select 
        username
        , datepart(week,local_date)  as Week
        , sum(hours) total
        , case when sum(case when DATENAME(dw, local_date) NOT IN ('Saturday', 'Sunday') then hours else 0 end) > 40 
                then 40
                else sum(case when DATENAME(dw, local_date) NOT IN ('Saturday', 'Sunday') then hours else 0 end) end as RegHours
        , sum(case when DATENAME(dw, local_date) IN ('Saturday', 'Sunday') then hours else 0 end) + 
            case when sum(case when DATENAME(dw, local_date) NOT IN ('Saturday', 'Sunday') then hours else 0 end) > 40 
                then sum(case when DATENAME(dw, local_date) NOT IN ('Saturday', 'Sunday') then hours else 0 end) - 40 else 0 end as OTHours
    from #timesheet 
    group by username, datepart(week, local_date)

    DROP TABLE #timesheet

username                       Week total   RegHours    OTHours
emilioh@thinkpowersolutions.com 22  74.00   40.00       34.00
emilioh@thinkpowersolutions.com 23  24.50   12.50       12.00

I find it easier to reason about the query if I abstract the weekend/weekday part out with a CTE first: 如果我先将周末/工作日部分抽象为CTE,就会发现对查询的推理更容易:

WITH HoursBuckets As
(
    SELECT username
        , DATEPART(week,local_date) As Week
        , SUM(hours) total
        , SUM(CASE WHEN DATENAME(dw, local_date) NOT IN ('Saturday', 'Sunday') THEN hours ELSE 0 END) As WeekDay
        , SUM(CASE WHEN DATENAME(dw, local_date) IN ('Saturday', 'Sunday') THEN hours ELSE 0 END) As WeekEnd
    FROM timesheet 
    GROUP BY username, DATEPART(week, local_date)
)
SELECT username, Week, Total,
   CASE WHEN Weekday > 40 THEN 40 ELSE Weekday END As RegularTime,
   CASE WHEN Weekday > 40 THEN Weekday - 40 ELSE 0 END + WeekEnd As OverTime
FROM HoursBuckets;

Results: 结果:

username                        Week    Total   RegularTime OverTime
emilioh@thinkpowersolutions.com 22      65      40          25
emilioh@thinkpowersolutions.com 23      34      25          9

If I understand correctly, RegularTime is the total hours MF to a MAX of 40hrs. 如果我理解正确,RegularTime是指总时数MF,最长为40小时。
OverTime is the total hours - 40 if the total hours is > 40. 加班是总小时数-如果总小时数> 40,则为40。
So you wouldn't need a day check on the Overtime because if they worked more than 40 hours in the workweek the extra hours would still be considered for overtime. 因此,您无需每天检查加班时间,因为如果他们在工作周中工作超过40个小时,则仍会考虑加班。

 select 
    username
    , datepart(week,local_date)  as Week
    , sum(hours) total
    , Case When sum(case when DATENAME(dw, local_date) NOT IN ('Saturday', 'Sunday') then hours else 0 end) <= 40
          Then sum(case when DATENAME(dw, local_date) NOT IN ('Saturday', 'Sunday') then hours else 0 end) Else 40 End as RegularTime
    , Case When sum(case when DATENAME(dw, local_date) NOT IN ('Saturday', 'Sunday') then hours else 0 end) > 40
          Then (sum(case when DATENAME(dw, local_date) NOT IN ('Saturday', 'Sunday') then hours else 0 end) - 40)
                + sum(case when DATENAME(dw, local_date) IN ('Saturday', 'Sunday') then hours else 0 end)
          Else sum(case when DATENAME(dw, local_date) IN ('Saturday', 'Sunday') then hours else 0 end) End as Overtime
from timesheet 
group by username, datepart(week, local_date);

OUTPUT: 输出:

username                        Week    total   RegularTime  OverTime
emilioh@thinkpowersolutions.com  22      65        40          25
emilioh@thinkpowersolutions.com  23      34        25           9

this solution differs only in that it has all the steps broken out into subqueries so you can see exactly what's going on at each step: 此解决方案的不同之处仅在于,它已将所有步骤分解为子查询,因此您可以准确了解每个步骤的工作情况:

 CREATE TABLE timesheet
  ([username] varchar(31), [local_date] datetime, 
   [hours] numeric(6,2), [wday] varchar(31));

INSERT INTO timesheet
    ([username], [local_date], [hours],[wday])
VALUES
    ('emilioh@thinkpowersolutions.com', '2015-05-24 19:00:00', 3.75,'Sun'),
    ('emilioh@thinkpowersolutions.com', '2015-05-25 19:00:00', 11,'Mon'),
    ('emilioh@thinkpowersolutions.com', '2015-05-26 19:00:00', 10.25,'Tue'),
    ('emilioh@thinkpowersolutions.com', '2015-05-27 19:00:00', 13,'Wed'),
    ('emilioh@thinkpowersolutions.com', '2015-05-28 19:00:00', 13,'Thu'),
    ('emilioh@thinkpowersolutions.com', '2015-05-29 19:00:00', 14,'Fri'),
    ('emilioh@thinkpowersolutions.com', '2015-05-30 19:00:00', 9,'Sat'),
    ('emilioh@thinkpowersolutions.com', '2015-05-31 19:00:00', 12,'Sun'),
    ('emilioh@thinkpowersolutions.com', '2015-06-01 19:00:00', 12.5,'Mon')    ;

select
  username, 
  week,
  sum_weekend_hours + sum_weekday_hours as total,
  case when sum_weekday_hours <= 40 then sum_weekday_hours else 40 end as Regulartime,
  sum_weekend_hours + 
     case when sum_weekday_hours <= 40 then 0 
     else sum_weekday_hours - 40  end as Overtime
from
  (select
    username, 
    Week,  
    sum(weekEndHours)  as sum_weekend_hours,
    sum(weekDayHours)  as sum_weekday_hours
  from 
    (select
        username,
        local_date,
        hours,
        wday,
        datepart(week,local_date) as Week, 
        datepart(weekday,local_date) as weekday,
        case when datepart(weekday,local_date) in (1,7) then hours else 0 end as weekEndHours,  -- sat, sun
        case when not(datepart(weekday,local_date) in (1,7)) then hours else 0 end as weekDayHours  -- sat, sun
      from 
        timesheet ) t
   group by
     username, 
     Week ) g;

SQL Fiddle SQL小提琴

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM