编写查询以查找以下结果

时间:2015-06-28 15:53:09

标签: sql sql-server

员工表:

EmpID EmpName    
----- --------------    
1     John Torres    
2     Irina Williams

薪资周表:

WeekID EmpID WeekStart  WeekEnd    
------ ----- ---------- ----------    
1      1     11-20-2011 11-26-2011
2      2     11-27-2011 12-03-2011
3      1     11-27-2011 12-03-2011

员工访问表:

ID EmpID VisitDate  StartTime EndTime Earningcode    
-- ----- ---------- --------- ------- -----------    
1  1     11-20-2011 10:00     12:00   Sat-Sun1    
2  1     11-21-2011 13:30     16:00   Mon-Fri1    
3  1     11-22-2011 14:00     15:00   Mon-Fri1    
4  1     11-24-2011 10:00     14:00   Mon-Fri1    
5  1     11-25-2011 13:30     16:00   Mon-Fri1    
6  1     11-26-2011 14:00     15:00   Sat-Sun1    
7  2     11-27-2011 09:00     11:00   Sat-Sun1    
8  2     11-28-2011 07:00     12:00   Mon-Fri1    
9  2     11-29-2011 09:00     11:00   Mon-Fri1    
10 2     12-03-2011 07:00     12:00   Sat-Sun1

预期结果

RecordType EmpID EmpName        WeekStart  WeekEnd    Earning code  Hours
---------- ----- -------------- ---------- ---------- ------------  -----
H          1     John Torres    11-20-2011 11-26-2011         
D                                                     Sat-Sun1     3.00
D                                                     Mon-Fri1     10.00
H          2     Irina Williams 11-27-2011 12-03-2011
D                                                     Sat-Sun1     7.00
D                                                     Mon-Fri1     7.00

1 个答案:

答案 0 :(得分:0)

虽然这种类型的格式(包含标题和详细信息)可能更适合在数据库之外(在实例的报告应用程序中),但它也可以在服务器上进行。

这样做的一种方法是结合两个不同的查询;一个用于标题,一个用于详细信息:

select RecordType, EmpID, EmpName, Week, WeekStart, WeekEnd, Earningcode, Hours 
from 
(
    select 'H' as RecordType, e.EmpID, EmpName, datepart(wk, WeekStart) as Week, WeekStart, WeekEnd, null as Earningcode, null as Hours
    from Employees e
    join PayrollWeek pw on pw.EmpID = e.EmpID
    join EmployeeVisits ev on e.EmpID = ev.EmpID and ev.VisitDate between pw.WeekStart and pw.WeekEnd
    group by e.EmpID, EmpName, WeekStart, WeekEnd, datepart(wk, WeekStart)
) H -- query for header rows
union all
(
    select 'D' as RecordType, ev.EmpID, null, datepart(wk, WeekStart) as WeekD, null, null, Earningcode, sum(datediff(minute, StartTime, EndTime))/60.0
    from EmployeeVisits ev
    join PayrollWeek pw on ev.VisitDate between pw.WeekStart and pw.WeekEnd and ev.EmpID = pw.EmpID
    group by ev.EmpID, Earningcode, datepart(wk, WeekStart)
) -- query for detail rows
order by EmpID, Week, RecordType desc, Earningcode desc

Sample SQL Fiddle

请注意,仅包含“周”列才能确保订购。

我在第3周为EmpId 1添加了一些用于演示的行,然后上面的查询会得到这个结果:

| RecordType | EmpID |        EmpName | Week |  WeekStart |    WeekEnd | Earningcode |  Hours |
|------------|-------|----------------|------|------------|------------|-------------|--------|
|          H |     1 |    John Torres |   48 | 2011-11-20 | 2011-11-26 |      (null) | (null) |
|          D |     1 |         (null) |   48 |     (null) |     (null) |    Sat-Sun1 |      3 |
|          D |     1 |         (null) |   48 |     (null) |     (null) |    Mon-Fri1 |     10 |
|          H |     1 |    John Torres |   49 | 2011-11-27 | 2011-12-03 |      (null) | (null) |
|          D |     1 |         (null) |   49 |     (null) |     (null) |    Mon-Fri1 |      2 |
|          H |     2 | Irina Williams |   49 | 2011-11-27 | 2011-12-03 |      (null) | (null) |
|          D |     2 |         (null) |   49 |     (null) |     (null) |    Sat-Sun1 |      7 |
|          D |     2 |         (null) |   49 |     (null) |     (null) |    Mon-Fri1 |      7 |