【问题标题】:Join table on a date between two dates in the target table在目标表中两个日期之间的日期连接表
【发布时间】:2017-08-09 14:14:08
【问题描述】:

我有两张桌子

tbl_TimeEntries 
   EmployeeID int,
   StartDateTime datetime,
   EndDateTime datetime

tbl_Crew_Employees
   CrewID,
   EmployeeID,
   StartDate,
   EndDate

我还有一个查询,可以生成每位员工每天工作的小时数,但我还想包括该员工当天所在的工作人员。

SELECT  tbl_TimeEntries.EmployeeID, 
        SUM(DATEDIFF(SECOND, StartDateTime, EndDateTime) / 60.0
                     / 60.0) as Hours,
        CAST(StartDateTime AS date) as WorkDate
FROM    tbl_TimeEntries 
GROUP BY tbl_TimeEntries.EmployeeID, CAST(StartDateTime AS date)
ORDER BY CAST(StartDateTime AS date)

我不确定如何在此查询中包含 CrewID,因为 tbl_Crew_Employees 使用 StartDate 和 EndDate(意味着员工从 StartDate 到 EndDate 一直在这个团队中)。我要么需要扩展 StartDate/EndDate 范围,要么使用某种我不知道的 SQL 魔法。

这是来自 tbl_Crew_Employees、tbl_TimeEntries 和当前查询的数据示例,其中添加了所需的列数据。 EmployeeID 88 代表样本中的两个不同的工作人员。

CrewID  EmployeeID  StartDate   EndDate

13      11          2013-03-30  2013-05-12
12      88          2013-01-02  2013-04-18
12      66          2013-01-02  2013-06-30
13      88          2013-04-19  2013-04-21
11      111         2013-01-02  2013-04-28

EmployeeID  StartDateTime       EndDateTime
11          2013-04-18 08:00    2013-04-18 12:00
11          2013-04-18 12:30    2013-04-18 18:30
111         2013-04-18 10:00    2013-04-18 12:00
111         2013-04-18 12:30    2013-04-18 18:30
88          2013-04-18 11:00    2013-04-18 12:00
88          2013-04-18 12:30    2013-04-18 19:30
66          2013-04-18 10:00    2013-04-18 12:00
66          2013-04-18 12:30    2013-04-18 18:30
11          2013-04-20 08:00    2013-04-20 12:00
11          2013-04-20 12:30    2013-04-20 18:00
111         2013-04-20 10:00    2013-04-20 12:00
111         2013-04-20 12:30    2013-04-20 18:30
88          2013-04-20 11:00    2013-04-20 12:00
88          2013-04-20 12:30    2013-04-20 19:30
66          2013-04-20 10:00    2013-04-20 12:00
66          2013-04-20 12:30    2013-04-20 17:00

EmployeeID  Hours   WorkDate        CrewID(desired)
11          10.00   2013-04-18      13
88          8.00    2013-04-18      12
66          8.00    2013-04-18      12
111         8.00    2013-04-18      11
11          7.50    2013-04-20      13
88          8.00    2013-04-20      13
66          6.50    2013-04-20      12
111         8.00    2013-04-20      11

【问题讨论】:

  • 可以添加几行示例数据吗?
  • 另外,请展示您希望最终结果的样子。
  • TimeEntries 的测试日期怎么样
  • 是否可以在同一天工作人员之间的工作流程?
  • 一名船员每天只能在一名船员上工作

标签: sql-server tsql


【解决方案1】:

试试这个:

SELECT 
    tbl_TimeEntries.employeeid
    ,SUM(DATEDIFF(SECOND, StartDateTime, EndDateTime) / 60.0 / 60.0) AS HOURS
    ,CAST(StartDateTime AS DATE) AS WorkDate
    ,tbl_Crew_Employees.crewid
FROM tbl_TimeEntries 
INNER JOIN tbl_Crew_Employees ON tbl_timeentries.employeeid = tbl_Crew_Employees.employeeid 
    AND startdatetime >= startdate 
    AND enddatetime <= enddate
GROUP BY tbl_TimeEntries.employeeid
        ,tbl_Crew_Employees.crewid
        ,CAST(tbl_TimeEntries.StartDateTime AS DATE)
ORDER BY WorkDate

【讨论】:

    【解决方案2】:

    应该是一个简单的连接。

    declare @tbl_Crew_Employees table(CrewID int, EmployeeID int, StartDate date, EndDate date)
    insert into @tbl_Crew_Employees
    values
    (13,11,'2013-03-30','2013-05-12'),
    (12,88,'2013-01-02','2013-04-18'),
    (12,66,'2013-01-02','2013-06-30'),
    (13,88,'2013-04-19','2013-04-21'),
    (11,111,'2013-01-02','2013-04-28')
    
    declare @tbl_TimeEntries table (EmployeeID int, StartDateTime datetime, EndDateTime datetime)
    insert into @tbl_TimeEntries
    values
    (11,'2013-04-18 08:00','2013-04-18 12:00'),
    (11,'2013-04-18 12:30','2013-04-18 18:30'),
    (111,'2013-04-18 10:00','2013-04-18 12:00'),
    (111,'2013-04-18 12:30','2013-04-18 18:30'),
    (88,'2013-04-18 11:00','2013-04-18 12:00'),
    (88,'2013-04-18 12:30','2013-04-18 19:30'),
    (66,'2013-04-18 10:00','2013-04-18 12:00'),
    (66,'2013-04-18 12:30','2013-04-18 18:30'),
    (11,'2013-04-20 08:00','2013-04-20 12:00'),
    (11,'2013-04-20 12:30','2013-04-20 18:00'),
    (111,'2013-04-20 10:00','2013-04-20 12:00'),
    (111,'2013-04-20 12:30','2013-04-20 18:30'),
    (88,'2013-04-20 11:00','2013-04-20 12:00'),
    (88,'2013-04-20 12:30','2013-04-20 19:30'),
    (66,'2013-04-20 10:00','2013-04-20 12:00'),
    (66,'2013-04-20 12:30','2013-04-20 17:00')
    
    SELECT  
        t.EmployeeID, 
        c.CrewID,
            SUM(DATEDIFF(SECOND, t.StartDateTime, t.EndDateTime) / 60.0
                         / 60.0) ,
            CAST(t.StartDateTime AS date)
    FROM    @tbl_TimeEntries t
    INNER JOIN 
        @tbl_Crew_Employees c on 
        c.EmployeeID = t.EmployeeID
        and c.StartDate <= cast(t.StartDateTime as date)
        and c.EndDate >= cast(t.EndDateTime as date)
    GROUP BY t.EmployeeID, CAST(t.StartDateTime AS date), c.CrewID
    ORDER BY CAST(t.StartDateTime AS date)
    

    【讨论】:

    • 实际上,这行不通。连接还必须包括双方的日期。员工在不同的日期在不同的工作人员,你的解决方案不提供。
    • 基于缺乏样本数据,那么我假设日期必须相等。见编辑。如果它们可以在几天之间流动,我们可以添加跨越逻辑——你只需要澄清
    • @scsimon 你有一些语法错误 - 你想更正它们,还是我应该?
    • 看起来您希望与样本数据不重叠@Paul ...查看编辑。
    猜你喜欢
    • 1970-01-01
    • 2022-06-10
    • 1970-01-01
    • 2010-10-05
    • 1970-01-01
    • 1970-01-01
    • 2021-05-22
    • 2021-03-14
    • 2018-09-17
    相关资源
    最近更新 更多