[SQL] 시간 중복에 대한 테이블을 확인?
SQL시간 중복에 대한 테이블을 확인?
나는 다음과 같은 필드가 MySQL의 테이블이 있습니다 :
STARTTIME 및 종료 시각은 MySQL의 TIME 필드 (하지 DATETIME)입니다. 나는 테이블에서 시간 범위의 모든 중복이 있는지 정기적으로 "스캔"테이블에 방법이 필요합니다. 10에서 00과 다른 : 00-11 : 30-11 : 10에서 이벤트가있는 경우 (30)가, 나는 시간의 중복의 존재의 경고가되고 싶어요.
아무것도 공상 정말 모든 I는 중복이 존재하는지 여부를 알고 싶어요.
나는 이것을 실행하기 위해 PHP를 사용하는거야.
해결법
-
==============================
1.이것은 내가 몇 년 전에 답을 발견하는 쿼리 패턴입니다 :
이것은 내가 몇 년 전에 답을 발견하는 쿼리 패턴입니다 :
SELECT * FROM mytable a JOIN mytable b on a.starttime <= b.endtime and a.endtime >= b.starttime and a.name != b.name; -- ideally, this would compare a "key" column, eg id
"어떤 중복"을 찾으려면, 당신은 서로와 기간의 반대 끝을 비교합니다. 그것은의 뭔가 내가 밖으로 펜과 종이를 얻고 가장자리의 경우는 이러한 비교에 아래로 삶은 것을 깨닫게 인접한 범위를 그릴 수 있었다.
당신이 겹치지 행을 방지하려면, 트리거에서이 쿼리의 변형을 넣어 :
create trigger mytable_no_overlap before insert on mytable for each row begin if exists (select * from mytable where starttime <= new.endtime and endtime >= new.starttime) then signal sqlstate '45000' SET MESSAGE_TEXT = 'Overlaps with existing data'; end if; end;
-
==============================
2.나는 일이 개 시간 범위가 겹치는 경우 확인하는 일반적인 기능을 원하는 것 또한 일정은 자정 전에 시작 및 종료 후, 같은 경우와 작업 "17 : 00 : 00-03 : 00 : 00"와 "14시 : 00-01 : 00 : I 보헤미안하여 용액을 개질되도록 00 "오버랩해야
나는 일이 개 시간 범위가 겹치는 경우 확인하는 일반적인 기능을 원하는 것 또한 일정은 자정 전에 시작 및 종료 후, 같은 경우와 작업 "17 : 00 : 00-03 : 00 : 00"와 "14시 : 00-01 : 00 : I 보헤미안하여 용액을 개질되도록 00 "오버랩해야
다음과 같이이 기능을 사용
SELECT func_time_overlap("17:00:00","03:00:00", "14:00:00","01:00:00")
또는이 같은 귀하의 경우
SELECT * FROM mytable a JOIN mytable b ON ( a.name != b.name AND func_time_overlap(a.starttime, a.endtime, b.starttime, b.endtime) );
여기서, 함수 정의는
CREATE FUNCTION `func_time_overlap`(a_start TIME, a_end TIME, b_start TIME, b_end TIME) RETURNS tinyint(1) DETERMINISTIC BEGIN -- there are only two cases when they don't overlap, but a lot of possible cases where they do overlap -- There are two time formats, one is an interval of time that can go over 24 hours, the other is a daily time format that never goes above 24 hours -- by default mysql uses TIME as an interval -- this converts a TIME interval into a date time format -- I'm not using `TIME(CAST(a_start AS DATETIME));` to convert the time interval to a time -- because it uses the current day by default and might get affected by the timezone settings of the database, -- just imagine the next day having the DST change. -- although the CAST should work fine if you use UTC IF a_start >= 24 THEN SET a_start = TIME(CONCAT(MOD(HOUR(a_start), 24),':',MINUTE(a_start),':',SECOND(a_start))); END IF; IF b_start >= 24 THEN SET b_start = TIME(CONCAT(MOD(HOUR(b_start), 24),':',MINUTE(b_start),':',SECOND(b_start))); END IF; IF a_end > 24 THEN SET a_end = TIME(CONCAT(MOD(HOUR(a_end), 24),':',MINUTE(a_end),':',SECOND(a_end))); END IF; IF b_end > 24 THEN SET b_end = TIME(CONCAT(MOD(HOUR(b_end), 24),':',MINUTE(b_end),':',SECOND(b_end))); END IF; -- if the time range passes the midnight mark, then add 24 hours to the time IF a_start >= a_end THEN SET a_end = a_end + INTERVAL 24 HOUR; END IF; IF b_start >= b_end THEN SET b_end = b_end + INTERVAL 24 HOUR; END IF; RETURN a_start < b_end AND a_end > b_start; END
나는 시간을 (CAST (AS DATETIME a_start)) 사용하지 않는; 그것은 기본적으로 현재 날짜를 사용하여 데이터베이스의 시간대 설정의 영향을받을 수 있기 때문에 시간에 시간 간격을 변환, 바로 DST 변화를 갖는 다음날 상상한다.
데이터베이스는 UTC 시간대 (예상대로)를 사용하는 경우에 당신은이를 사용할 수 있습니다
IF a_start >= 24 THEN SET a_start = TIME(CAST(a_start AS DATETIME)); END IF; IF b_start >= 24 THEN SET b_start = TIME(CAST(b_start AS DATETIME)); END IF; IF a_end > 24 THEN SET a_end = TIME(CAST(a_end AS DATETIME)); END IF; IF b_end > 24 THEN SET b_end = TIME(CAST(b_end AS DATETIME)); END IF;
-
==============================
3.이 시도:
이 시도:
declare @tempTbl table(RecID) insert into @tempTbl Select RecID from ( Select t.RecID from Table1 t,Table1 t1 where t.StartTime between t1.StartTime AND t1.EndTime AND t.RecID <> t1.RecID )
-
==============================
4.그것은 나를 위해 작동이 시도
그것은 나를 위해 작동이 시도
SELECT * from Shedulles a where exists ( select 1 from Shedulles b where a.ShedulleId != b.ShedulleId and ( a.DateFrom between b.DateFrom and b.DateTo or a.DateTo between b.DateFrom and b.DateTo or b.DateFrom between a.DateFrom and a.DateTo ) and a.DateFrom != b.DateTo and b.DateFrom != a.DateTo );
또는이 하나
SELECT DISTINCT a.* FROM Shedulles a JOIN Shedulles b ON a.ShedulleId != b.ShedulleId and ( a.DateFrom between b.DateFrom and b.DateTo or a.DateTo between b.DateFrom and b.DateTo or b.DateFrom between a.DateFrom and a.DateTo ) and a.DateFrom != b.DateTo and b.DateFrom != a.DateTo
from https://stackoverflow.com/questions/6571538/checking-a-table-for-time-overlap by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] 왜 SQL에는 제품 집계 함수가 없다? (0) | 2020.04.15 |
---|---|
[SQL] 어떻게 PostgreSQL의 트리거에서 이메일을 보낼 수 있습니까? (0) | 2020.04.15 |
[SQL] SQL - 어떻게 트랜스 하는가? (0) | 2020.04.15 |
[SQL] (*) 또는 카운트 더 나은 MYSQL 수있는 무엇입니까 (1)? (0) | 2020.04.15 |
[SQL] null 값과 MySQL의 비교 (0) | 2020.04.15 |