2016-07-28 3 views
-2

운송 업계에서 규정은 서비스 시간을 제한합니다.시작 및 중지 필드가있는 연속적인 datetime 레코드를 찾기위한 mysql 쿼리

나는 Task_ID라는 AUTO_INCREMENT 필드, User_ID라는 외부 키를 갖는 정수 필드, 2 개 개의 날짜 필드, Start_DTEnd_DT있는 테이블을 포함하는 MySQL 데이터베이스가 있습니다.

테이블 : 여러 작업을 포함 할 수

Task_ID | User_ID | Start_DT | End_DT 

직원의 변화는 각 레코드를 생성.

직원 (User_ID)에 의해 가장 최근의 종료 시간을 식별하는 쿼리가 이미 있습니다. (html 사용자 인터페이스는 시작 시간이 endtime보다 늦은 데이터 입력을 방지합니다.)

(종업원별로) 가장 최근의 endtime에 인접한 모든 레코드를 반환하는 쿼리를 만들어야합니다. 즉, 현재 레코드의 시작 시간이 이전 레코드의 종료 시간 (직원 기준)과 동일한 모든 레코드입니다. 시리즈의 작업 (레코드) 수는 다양합니다.

인접한 일련의 작업이 작업 수를 초과하지 않을만큼 충분한 하위 쿼리를 중첩해야합니까? 아니면 간격을 찾고 간격보다 나중에 모든 레코드를 반환 할 수있는 방법이 있습니까?

단일 필드에서 간격을 찾는 데 많은 조언이 있지만이 검색에는 내 검색이 적합하지 않습니다.

이 ...

CREATE TABLE `hoursofservice` (
    `Task_ID` MEDIUMINT(8) UNSIGNED NOT NULL AUTO_INCREMENT, 
    `User_ID` SMALLINT(5) UNSIGNED NOT NULL, 
    `Location` VARCHAR(20) NULL DEFAULT NULL, 
    `Task` VARCHAR(30) NULL DEFAULT NULL, 
    `Start_DT` DATETIME NOT NULL, 
    `End_DT` DATETIME NULL DEFAULT NULL, 
    `Comment_1` VARCHAR(20) NULL DEFAULT NULL, 
    `Comment_2` VARCHAR(256) NULL DEFAULT NULL, 
    `Bad_Data` BIT(1) NOT NULL DEFAULT b'0', 
    PRIMARY KEY (`Task_ID`), 
    UNIQUE INDEX `Task_ID` (`Task_ID`), 
    INDEX `FK_hoursofservice_employee_id` (`User_ID`), 
    CONSTRAINT `FK_hoursofservice_employee_id` FOREIGN KEY (`User_ID`) REFERENCES `employee_id` (`User_ID`) ON UPDATE CASCADE 

INSERT INTO hoursofservice (User_ID, Location, Task, Start_DT, End_DT, Comment_1, Comment_2) 
SELECT User_ID, Location, Task, Start_DT, End_DT, Comment_1, Comment_2 FROM read_text_file; 

2) 결과 세트를 (:)

1 이하로 딸기의 의견에 응답하는) 레코드는 테이블에서 선택 될 것이다 그러한 가장 최근 레코드의 시작 시간은 이전 레코드의 종료 시간과 같고, 조건을 만족하는 레코드가 없을 때까지 동일합니다. (이들은 USER_ID으로 정렬됩니다.)이 같은

+0

당신이 행동이 2 단계의 간단한 과정 다음 사항을 고려 좋아하는 경우 : 당신이 이미하지 않은 경우 1. 따라서 문제를보다 쉽게 ​​복제 할 수 있도록 적절한 CREATE 및 INSERT 문 (및/또는 sqlfiddle)을 제공하십시오. 2. 아직 수행하지 않은 경우 1 단계에서 제공된 정보와 일치하는 원하는 결과 세트를 제공하십시오. – Strawberry

+0

코칭에 감사드립니다. 나는 그 프로토콜의 초보자이다. – dirk

+0

저희에게 말하지 마십시오. 우리에게 보여줘! – Strawberry

답변

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 
; 
+0

신속한 답변을 해주셔서 감사 드리며, DoubleU-ear-dough. 사장님이 저를 다른 어떤 곳으로 데려 오니, 오늘까지 당신의 해결책을 시도 할 기회가 없었습니다. 사용할 MySQL 버전은 5.3.3입니다. 테이블 별칭 "t"가 마음에 들지 않지만 "t"가 테이블 이름으로 바뀌면 실행됩니다. 불행히도 연속 된 레코드 사이의 첫 번째 간격이 아니라 가장 최근의 레코드를 반환합니다. 어떤 아이디어? – dirk

+0

당신이 시도한 쿼리를 보지 않고서는, 내 첫 번째 추측은 "theTable"의 모든 필드별로 그룹화하지 않았을 것입니다 ... (오, 그리고 아마도't'가 마음에 들지 않는 이유는 아마도 내가 가지고 있으면 안되기 때문일 것입니다 그런 식으로 바깥 쪽 질의에 사용됨). 1 행의 't. *'은 문자 그대로 't. *'가 아니라 'theTable'의 모든 필드를 나타 내기위한 것입니다.지금 생각해 보면 편집을 할 것입니다. 왜냐하면 이제는 GROUP BY 나 HAVING을 사용하지 않기 때문에 다른 레이어를 필요로 할 것입니다. – Uueerdo

+0

3 행과 12 행의 SELECT 문은 13 행에 설정된 별칭을 사용합니까? 나는 [fieldname], [fieldname]뿐만 아니라 [tablename]. [fieldname], [fieldname]을 사용해 보았습니다. 그리고 이것들을 개별적으로 backticks로 둘러 보았습니다. 모든 변형은 "SQL 오류 (1054) 알 수없는 열 t. [fieldname] 필드 목록에서 반환합니다." 어떤 아이디어? – dirk

관련 문제