mysql查询以查找带有start和stop字段的连续日期时间记录

时间:2016-07-28 17:50:15

标签: mysql

在运输行业,法规限制了服务时间。

我有一个mysql数据库,其中包含一个名为¬的auto_increment字段的表,一个名为Task_ID的外键的整数字段,以及两个日期时间字段User_ID和{ {1}}。

表:

Start_DT

员工的转变可以包括多个任务,每个任务都创建一个记录。

我已经有一个查询,按员工(End_DT)标识最近的结束时间。 (html用户界面可以防止数据输入,其中启动时间晚于结束时间。)。

我需要创建一个查询,该查询将返回与最近的最终结束时间相邻的所有记录(按员工)。换句话说,当前记录的开始时间等于前一记录的结束时间(按员工)的所有记录。系列中的任务(记录)数量各不相同。

我是否应该嵌套足够的子查询以确信没有连续的任务系列会超过任务数量,或者是否有办法寻找差距并在间隙之后返回所有记录?

在单个字段中找到差距有很多建议,但我的搜索并不适合这个问题。

(回应草莓的评论如下:)

1)

 Task_ID | User_ID | Start_DT | End_DT

和......

User_ID

2)结果集将是从表中选择的记录,使得最近记录的开始时间等于前一个记录的结束时间,同样直到没有符合条件的记录。 (这些将按User_ID排序。)

1 个答案:

答案 0 :(得分:0)

这样的事可能适合你:

SELECT islands.[all relevant fields from "theTable"]
FROM (
    SELECT [all relevant fields from "theTable"]
        , @i := CASE
             WHEN @prevUserId <> User_ID THEN 1 -- Reset "island" counter for each user
             WHEN @prevStart <> End_DT THEN @i + 1 -- Increment "island" counter when gaps found
             ELSE @i -- Do not change "island" counter
             END AS island
        , @prevStart := Start_DT -- Remember this Start_DT value for the next row
        , @prevUserId := User_ID -- Remember this User_ID value for the next row
    FROM (
        SELECT t.*
        FROM theTable AS t
        WHERE End_DT < [known or "ceiling" End_DT]
           AND [limiting condition (for speed), 
                something like Start_DT > [ceiling] - INTERVAL 3 DAY
               ]
        ORDER BY User_ID, End_DT DESC
    ) AS candidates -- Insures rows are in appropriate order for use with session variables.
                    -- Allows us to treat the inclosing query somewhat like a loop.
    , (SELECT @i := 0
             , @prevStart := '9999-12-31 23:59:59'
             , @prevUserId := -1
      ) AS init -- Initializing session variables; 
                -- can actually be done in preceeding SET statements 
                -- if the connection is preserved between the SETs and the query.
    ORDER BY User_ID, Start_DT
) AS islands -- Data from "theTable" should now have appropriate "islands" calculated
WHERE islands.island = 1 -- Only keep the first "island" for each user
ORDER BY islands.User_ID, islands.Start_DT
;