SQL案例选择

时间:2010-11-17 17:15:52

标签: sql sql-server

也许有人可以帮助我

我有一个用于记录员工离职的SQL数据库。我们有许多不同的转变,在我们的员工表上,我们有7个字段代表他们工作的日子。这些是一种数据类型,1表示当天工作,0表示不工作。

第二张表让所有员工离开。包含员工ID,请假日期和原因。

我可以轻松查询员工表,了解一周中任何一天的工作人数,我可以轻松查询请假表,查看在给定日期有多少人离开。

我想要做的是根据休假表中的星期几,计算那天应该有多少人。

尝试创作的代码是

select TBL_Leave.Leave_Date AS 'Date',
    datepart(weekday,TBL_Leave.Leave_Date) - 1 AS 'Day Of Week',
    count(TBL_Leave.Leave_Date) AS 'Total Off',

    case
        when datepart(weekday,TBL_Leave.Leave_Date) - 1 = 5 then select SUM(convert(int,Mon)) from TBL_Employees)
        else 'Flase'
    end

from TBL_Leave

where Leave_Date between '2010-01-01' AND '2010-12-31'

group by TBL_Leave.Leave_Date

但果然,它不起作用。

我试图计算从一张桌子开始工作的人数,根据一周中某一天的字段来计算。

任何人都可以给予的任何帮助都会很棒

欢呼声 保罗


我有这个查询来了解有多少人在任何日期关闭

select TBL_Leave.Leave_Date AS 'Date',
    datepart(weekday,TBL_Leave.Leave_Date) - 1 AS 'Day Of Week',
    count(TBL_Leave.Leave_Date) AS 'Total Off'

from TBL_Leave

where Leave_Date between '2010-01-01' AND '2010-12-31'

group by TBL_Leave.Leave_Date

这可以看到任何一天有多少人

select SUM(convert(int,Mon)) as 'Monday',
       SUM(convert(int,Tue)) AS 'Tuesday',
       SUM(convert(int,Wed)) AS 'Wednesday',
       SUM(convert(int,Thu)) AS 'Thursday',
       SUM(convert(int,Fri)) AS 'Friday',
       SUM(convert(int,Sat)) AS 'Saturday',
       SUM(convert(int,Sun)) AS 'Sunday'

from TBL_Employees

where planned = 1

5 个答案:

答案 0 :(得分:3)

恕我直言,你应该设置一个视图作为这样的查询的帮助:

create view V_EmployeeWorkingDays as
select EmployeeID,
       case ShortDayName
       when 'Mon' then 1 when 'Tue' then 2 when 'Wed' then 3
       when 'Thu' then 4 when 'Fri' then 5 when 'Sat' then 6
       when 'Sun' then 7 end as weekday,
       IsWorking
from   TBL_Employees
unpivot (IstWorking for ShortDayName in (Mon,Tue,Wed,Thu,Fri,Sat,Sun)) p;

其次,您需要在您的范围内的日历日期。你可以使用这样的函数:

create function F_DateValues(@FromDate datetime, @ToDate datetime)
returns table as
return (
    select  dateadd(day,Nr-1,@FromDate) as Date
    from    (select  row_number() over (rand()) as Nr
            from    (values (1),(1),(1),(1)) a
            cross join (values (1),(1),(1),(1)) b 
            cross join (values (1),(1),(1),(1)) c
            cross join (values (1),(1),(1),(1)) c) n
    where   Nr > datediff(day,@FromDate,@ToDate)
);

现在你可以把它全部放在一起:

select  d.Date,
        isnull(w.CountWorkingPlanned,0)-isnull(l.CountLeaves,0) as CountWorking
from    F_DateValue('20101118','20101128') d
left join (select LeaveDate, count(*) as CountLeaves
           from TBL_LeaveDate group by LeaveDate) l
    on  l.LeaveDate = d.Date
left join (select weekday, count(*) as CountWorkingPlanned
           from V_EmployeeWorkingDays where IsWorking=1 group by weekday) w
    on w.weekday = datepart(weekday,d.Date);

这应该有效(没有经过测试 - 所以请不要因为打字错误而杀了我;))。

答案 1 :(得分:2)

您应该重新设计表格布局。由于每个工作日都有一个字段,这意味着您在字段名称中有数据。数据属于表中,因此您应该将该数据作为行放在单独的表中。

然后很容易获得数据。例如:

select count(*)
from Employees e
left join Leave l on l.EmployeeId = e.EmployeeId and LeaveDate = @Today
left join Workdays w on w.EmployeeId = e.EmployeeId and w.WeekDay = datepart(weekday, @Today)
where l..EmployeeId is null and w.EmployeeId is null

答案 2 :(得分:0)

SELECT count(id) FROM employee WHERE monday = true

似乎很容易,除非我仍然没有得到你需要的东西......

答案 3 :(得分:0)

这是一个可能适合您的查询。

查询使用派生查询来获取请假和工作计数。我在TBL_Employee数据上包含了一个UNPIVOT操作,以便更容易获取员工数据。您可以通过已建议的设计更改来避免这种情况。

SELECT Leave.Leave_Date, WorkCount, LeaveCount,
       WorkCount-LeaveCount AS CountDifference
FROM
    (
    -- Get Leave counts by date
    SELECT Leave_Date, UPPER(LEFT(DATENAME(dw, Leave_Date), 3)) AS WorkDay,
        COUNT(*) as LeaveCount
    FROM TBL_Leave
    WHERE Leave_Date between '2010-01-01' AND '2010-12-31'
    GROUP BY Leave_Date, UPPER(LEFT(DATENAME(dw, Leave_Date), 3))
    ) AS Leave
LEFT OUTER JOIN
    (
    -- Get Work counts by day of week
    SELECT WorkDay, COUNT(*) WorkCount
    FROM 
       (
       SELECT EmpID, Mon, Tue, Wed, Thu, Fri, Sat, Sun
       FROM TBL_Employees
       ) p
        UNPIVOT
           (IsWorking FOR WorkDay IN 
              (Mon, Tue, Wed, Thu, Fri, Sat, Sun)
           )AS unpvt
    WHERE unpvt.IsWorking = 1
    GROUP BY WorkDay
    ) AS Work ON Leave.WorkDay = Work.WorkDay  -- Join on day of week

答案 4 :(得分:0)

感谢大家对此的帮助,我已经找到了一些提示。昨晚我设法将它排序,当我看到它时,我想我觉得它听起来比它更复杂。这是我想出来的。

create table TEMP_planned (id int null, mon int null, tue int null, wed int null, thur             int null, fri int null, sat int null, sun int null)

insert into TEMP_planned (id, mon, tue, wed, thur, fri, sat, sun) 

values(1,
(select SUM(convert(int,Mon)) from TBL_Employees where Planned = 1),
(select SUM(convert(int,Tue)) from TBL_Employees where Planned = 1),
(select SUM(convert(int,Wed)) from TBL_Employees where Planned = 1),
(select SUM(convert(int,Thu)) from TBL_Employees where Planned = 1),
(select SUM(convert(int,Fri)) from TBL_Employees where Planned = 1),
(select SUM(convert(int,Sat)) from TBL_Employees where Planned = 1),
(select SUM(convert(int,Sun)) from TBL_Employees where Planned = 1))


select  TBL_Leave.Leave_Date,   
    'Planned' = case DATEPART(dw,TBL_Leave.Leave_Date) - 1
        when 1 then (select mon from TEMP_Planned where ID = 1)
        when 2 then (select tue from TEMP_Planned where ID = 1)
        when 3 then (select wed from TEMP_Planned where ID = 1)
        when 4 then (select thur from TEMP_Planned where ID = 1)
        when 5 then (select fri from TEMP_Planned where ID = 1)
        when 6 then (select sat from TEMP_Planned where ID = 1)
        when 7 then (select sun from TEMP_Planned where ID = 1)
    end,
    COUNT(tbl_leave.Leave_Date) as 'Total Staff Off'    

from TBL_Leave

group by    TBL_Leave.Leave_Date

drop table temp_planned