SQL数据库表连接创建IdealTable

时间:2018-01-06 09:50:13

标签: sql sql-server database join

我需要一些帮助来加入我目前的表格。

离开,加时赛和名册的日期,员工ID需要匹配

注意:ShiftDuration设置为默认值= 8.25

注意:当员工申请休假和加班时,请假和加班表只有条目。

Employee
EmplyeeeID | Username | Password | GivenName | FamilyName | TeamID | ContactNo | StaffType
------------------------------------------------------------------------------------------
  123         123        abc        John          Snow        1         999          1
  1234        1234       abcd       Jack         Waller       2         223          1 
  12345       12345      abcde       Ali           Saw        1         123          1
  123456      123456     abcdef     Peter         Peter       2         223          1
  1234567     1234567    abcdeg     Bryan         Peter       1         333          1


Roster
Duty_ID | EmployeeID |      Date        | ShiftType | ShiftDuration
--------------------------------------------------------------------
   2       123             2018-05-05         1          8.25
   4       1234            2018-05-04         1          8.25
   5       12345           2018-05-05         1          8.25
   7       123456          2018-05-04         1          8.25
   8       1234567         2018-05-05         1          8.25


Overtime
OTID | EmployeeID |     Date     | OT_Duration | OT_Reason
------------------------------------------------------------
 2        1234        2018-05-04        2        Cover Duty

Leave
LeaveID | EmployeeID |   Date    | Duration_Off | Reason
----------------------------------------------------------
 3            123      2018-05-05        2         NIL


IdealTable (Via Query)
   Date    | EmployeeID | GivenName | FamilyName | TeamID | ShiftType | ShiftDuration | Duration_Off | OT_Duration | Total_Hours
---------------------------------------------------------------------------------------------------------------------------------
2018-05-05      123         John         Snow         1         1             8.25            2             0            6.25
2018-05-04      1234        Jack        Waller        1         1             8.25            0             2            10.25
2018-05-05      12345       Ali           Saw         1         1             8.25            0             0            8.25
2018-05-04      123456      Peter         Peter       1         1             8.25            0             0            8.25
2018-05-05      1234567     Bryan         Peter       1         1             8.25            2             0            8.25

我有4张桌子,他们是员工,休假,加班,名册

Employee
-EmployeeID (PK)
-Username
-Password
-GivenName
-FamilyName
-TeamID
-ContactNo
-StaffType

Leave
-LeaveID (PK)
-EmployeeID (FK)
-Date
-Duration_Off
-Reason

Overtime
-OTID (PK)
-EmployeeID (FK)
-Date
-OT_Duation
-OT_Reason

Roster
-DutyID (PK)
-EmployeeID (FK)
-Date
-ShiftType
-Shift Duration (Default Value = 8.25)

我要做的是使用Query

加入这4个表中的数据
Ideal Table
-Date (From Leave, Overtime and Roster Table)
-EmployeeID (Employee Table)
-GivenName (Employee Table)
-FamilyName (Employee Table)
-TeamID (Employee Table)
-ShiftType (Roster Table)
-ShiftDuration (Roster Table)
-Duration_Off (Leave Table)
-OT_Duration (Overtime Table)
-Total_Hours (Calculation from joint table [(ShiftDuration + OT_Duration) - Duration_Off]

My database diagram design请忽略TimeData表,因为我最初想使用TimeData表来实现IdealTable

我当前的查询

USE [SMRT Dashboard]
GO

;With Dates
AS
(
SELECT [Date] FROM dbo.Roster
UNION 
SELECT [Date] FROM dbo.Leave
UNION
SELECT [Date] FROM dbo.Overtime
),
Work_Matrix
AS
(
SELECT EmployeeID,[Date],ShiftType,ShiftDuration,CAST(NULL AS Decimal(30,2)) AS Duration_Off,CAST(NULL AS Decimal(30,2)) AS OT_Duration
FROM dbo.Roster
UNION ALL
SELECT EmployeeID,[Date], NULL, NULL,Duration_Off
FROM dbo.Leave
UNION ALL
SELECT EmployeeID,[Date],NULL,NULL,NULL,OT_Duration
FROM dbo.Overtime
)

SELECT d.[Date],
e.EmployeeID,
e.GivenName,
e.FamilyName,
e.TeamID,
w.ShiftType,
w.ShiftDuration,
w.Duration_Off,
w.OT_Duration,
w.Total_Hours
FROM  Dates d
INNER JOIN
(
SELECT EmployeeID,
[Date],
MAX(ShiftType) AS ShiftType,
SUM(ShiftDuration) AS ShiftDuration,
SUM(Duration_Off) AS Duration_Off,
SUM(OT_Duration) AS OT_Duration,
SUM(ShiftDuration) + SUM(OT_Duration) - SUM(Duration_Off) AS Total_Hours
FROM Work_Matrix
GROUP BY EmployeeID,
[Date]
)w
ON d.[Date] = w.[Date]
JOIN dbo.Employee e
ON e.EmployeeID = w.EmployeeID

当前错误:

Msg 205, Level 16, State 1, Line 4
All queries combined using a UNION, INTERSECT or EXCEPT operator must have an equal number of expressions in their target lists.

4 个答案:

答案 0 :(得分:0)

我没有测试过这个,但你现在可以检查一下。希望你的问题能够得到解决。

SELECT 
a.EmployeeID,
a.GivenName,
a.FamilyName,
a.TeamID,
d.ShiftType,
d.ShiftDuration,
b.Duration_Off,
c.OT_Duration,
b.Date,
(d.ShiftDuration + c.OT_Duration) - b.Duration_Off as Total_Hours
FROM Employee a
INNER JOIN Roster d ON  a.EmployeeID = d.EmployeeID 
LEFT JOIN Leave b ON a.EmployeeID = b.EmployeeID 
LEFT JOIN Overtime c ON  a.EmployeeID = c.EmployeeID 

我假设Date在所有三个表中都是相同的(离开,加班和名册表)

答案 1 :(得分:0)

尝试此查询:

select 
l.Date,
o.Date,
r.Date,
e.EmployeeID,
e.GivenName,
e.FamilyName,
e.TeamID,
r.ShiftType,
r.ShiftDuration,
l.Duration_Off,
o.OT_Duration,
((r.ShiftDuration+o.OT_Duration)-l.Duration_Off) as Total_Hours
FROM Employee e
INNER JOIN Leave l ON e.EmployeeID = l.EmployeeID 
INNER JOIN Overtime o ON  e.EmployeeID = o.EmployeeID 
INNER JOIN Roster r ON  r.EmployeeID = r.EmployeeID;

答案 2 :(得分:0)

试试此查询!您将获得正确的输出。

SELECT 
e.EmployeeID AS 'Emp ID',
e.GivenName AS 'Emp Name',
l.Date AS Date,
e.FamilyName AS 'Family Name',
e.TeamID AS 'Team ID',
r.ShiftType AS 'Shift Type',
r.ShiftDuration AS 'Shift Duration',
l.Duration_Off AS 'Duration Off',
o.OT_Duration AS 'OT Duration',
(r.ShiftDuration + o.OT_Duration) - l.Duration_Off as 'Total Hours'
FROM 
Employee e,
Leave l,
Overtime o,
Roster r
WHERE
e.EmployeeID = l.EmployeeID
AND
e.EmployeeID = o.EmployeeID
AND
e.EmployeeID = r.EmployeeID

答案 3 :(得分:0)

我认为这里的问题是员工可能有休假,可能有加班,或者两者都没有。通过使用INNER JOIN,您可以将该组员工过滤为具有“离开”和“名册”的员工,并加班。

我创建了一个SqlFiddle,其中包含您提供的数据(请参阅here),它可以让您更接近。

  SELECT 
    COALESCE(r.Date, o.Date, l.Date) as Date,
    e.EmployeeID,
    e.GivenName,
    e.FamilyName,
    e.TeamID,
    r.ShiftType,
    r.ShiftDuration,
    IFNULL(l.Duration_Off, 0) as Duration_Off,
    IFNULL(o.OT_Duration, 0) as OT_Duration,
    r.ShiftDuration + IFNULL(o.OT_Duration, 0) - IFNULL(l.Duration_Off, 0) as Total_Hours
  FROM Employee e
  INNER JOIN Roster r on
    e.EmployeeID = r.EmployeeID
  LEFT JOIN Overtime o on
    e.EmployeeID = o.EmployeeID
  LEFT JOIN `Leave` l on
    e.EmployeeID = l.EmployeeID

这个查询无法解决几个cavaets:

  • 如果员工有多个休假条目或多个加班条目,该人将被列出N次。您可以使用GROUP BY语句来处理此
  • 您问题中的示例数据无法正确协调。例如,员工1234在5/4/2018有一个班次,在5/5/2018有OT,但在5/4/2018有10.25。

如果您使用TimeData,这将变得更加容易(假设每个员工每个日期有一条记录):

SELECT 
  COALESCE(r.Date, o.Date, l.Date) as Date,
  e.EmployeeID,
  e.GivenName,
  e.FamilyName,
  e.TeamID,
  r.ShiftType,
  IFNULL(r.ShiftDuration, 0) as ShiftDuration,
  IFNULL(l.Duration_Off, 0) as Duration_Off,
  IFNULL(o.OT_Duration, 0) as OT_Duration,
  IFNULL(r.ShiftDuration, 0) + IFNULL(o.OT_Duration, 0) - IFNULL(l.Duration_Off, 0) as Total_Hours
from TimeData t
INNER JOIN Employee e on
  t.EmployeeID = e.EmployeeID
LEFT JOIN Roster r on
  t.Duty_ID = r.Duty_ID
LEFT JOIN Overtime o on
  t.OTID = o.OTID
LEFT JOIN `Leave` l on
  t.LeaveID = l.LeaveID 

可以找到示例SqlFiddle here