복붙노트

[SQL] 같은 테이블에서 날짜 범위를 중복 감지

SQL

같은 테이블에서 날짜 범위를 중복 감지

나는 다음과 같은 데이터로 테이블이

PKey  Start       End         Type
====  =====       ===         ====
01    01/01/2010  14/01/2010  S
02    15/01/2010  31/01/2010  S
03    05/01/2010  06/01/2010  A

그리고 다음과 같은 결과를 얻으려면

PKey  Start       End         Type
====  =====       ===         ====
01    01/01/2010  14/01/2010  S
03    05/01/2010  06/01/2010  A

시작 위치에 대한 어떤 아이디어? 이 내가했던 많은 독서는 이것이 유일한 방법은, 내가 항목을 만들 필요가 매일과 일치하는 일에 참여 제안?

해결법

  1. ==============================

    1.당신은 이미 작동합니다 매일 항목을 가지고 있지만, 그렇게하지 않으면 해당 쿼리가 자주 사용하는 경우 성능에 영향을 미칠 경우 오버 헤드가 중요하다, 그리고합니다.

    당신은 이미 작동합니다 매일 항목을 가지고 있지만, 그렇게하지 않으면 해당 쿼리가 자주 사용하는 경우 성능에 영향을 미칠 경우 오버 헤드가 중요하다, 그리고합니다.

    데이터가이 형식에있는 경우 주어진이 완료되기 전에, 당신은 뭔가를 중복 주어진 간격 후 단순히 하나의 간격 시작이기 때문에, 간단한 날짜 연산을 사용하여 중복 감지 할 수 있지만,

    select dr1.* from date_ranges dr1
    inner join date_ranges dr2
    on dr2.start > dr1.start -- start after dr1 is started
      and dr2.start < dr1.end -- start before dr1 is finished
    

    당신이 간격 특수 처리가 필요한 경우 다른 구간 내 전부, 또는 당신은 병합 간격, 즉 필요가

    PKey  Start       End         Type
    ====  =====       ===         ====
    01    01/01/2010  20/01/2010  S
    02    15/01/2010  31/01/2010  S
    

    굽힐 수 있는

    Start       End         Type
    =====       ===         ====
    01/01/2010  31/01/2010  S
    

    당신은 더 복잡한 계산이 필요합니다.

    문제가 이런 종류의 내 경험에 의하면, 당신은 손으로 계산을 수행하는 방법에 도착하면, 그것은 SQL로 전송하기 쉽습니다 :)

  2. ==============================

    2.나는 중복에 대한 SQL에서 두 시간 범위를 비교하기 위해 필요한 경우, 여기에 내가 생각할 수있는 네 가지 시나리오는 다음과 같습니다

    나는 중복에 대한 SQL에서 두 시간 범위를 비교하기 위해 필요한 경우, 여기에 내가 생각할 수있는 네 가지 시나리오는 다음과 같습니다

    여기에 내가 (내 경우 오라클 SQL에서) 이러한 시나리오를 캡처하기 위해 만든 OR 문은 다음과 같습니다

    and (
        s1.start between s2.start and s2.end
        OR
        s1.end between s2.start and s2.end
        OR
        s2.start between s1.start and s1.end
    )
    
  3. ==============================

    3.혹시:

    혹시:

    SELECT A.PKey, A.Start, A.End, A.Type
    FROM calendar AS A, calendar AS B
    WHERE (p.pkey<>a.pkey
    AND b.start>=a.start
    AND b.end<=a.end)
    OR (b.pkey<>a.pkey
    AND b.start<=a.start
    AND b.end>=a.end)
    
  4. ==============================

    4.

    select A.*
    from MyTable A
    inner join MyTable B
    on (B.start <= A.end)
    and (B.end >= A.start)
    

    또는 같은 (가정 날짜는 널이 아니며 동일한 날짜 오버랩으로 계산).

  5. ==============================

    5.MySQL의에서 당신은 기본적으로 필요합니다 :

    MySQL의에서 당신은 기본적으로 필요합니다 :

    SELECT COUNT (*) A와 date_ranges로부터, B를 AS date_ranges WHERE A.id <> B.id 및 A.id> B.id 및 A.end_at> B.start_at 및 B.end_at> A.start_at

    > 번째 및 세 번째 문에 따를> =로 대체 될 수는 매칭을 포함한다.

    이 항목은 "알렌의 간격 대수학"에 관련이에 좀 더 읽기가 그 연결에 의해이 발견 될 수있다 :

  6. ==============================

    6.우리는 오랫동안 우리의 쿼리의 조건을 중복의이 종류를 필요로했고 나는 여기 정말 간단한 해결책을 찾은 것 같아요.

    우리는 오랫동안 우리의 쿼리의 조건을 중복의이 종류를 필요로했고 나는 여기 정말 간단한 해결책을 찾은 것 같아요.

    내 응용 프로그램에서, 예를 들어, 나는 같은 정책 번호를 가지고 있지만 어쩌면 정책 설명이 다음 한 회계 연도에서 변경 정책을 가지고있다. 사용자가 새 레코드 (같은 정책 번호, 다른 정책 설명)를 입력하면, 그 정책이 이미 지정된 시간 범위에 대해 존재하는지 알 수있는 방법이 필요했습니다. 효과적인 / 만료 날짜가 어떤과 중복 새로운 정책이 데이터베이스에 이미있는 경우에, 나는 밖으로 오류와 그 입력이 정확하지 왜 사용자에게 필요합니다.

    이를 위해, 나는 다음과 같은 조건 문으로 갔다 :

    AND @_expiration >= EffectiveDate AND ExpirationDate >= @_effective
    

    내가 가지고있는 희망의 다른 사람이 유용으로이를 찾습니다.

  7. ==============================

    7.나는 테이블에 입력되는 중복 휴일을 중지 할 수있는 매우 비슷한 일을했다. 그렇게 VBA SQL에서 쿼리를했다 액세스에 있었고, 입력에 TEMPTABLE에 기록 :

    나는 테이블에 입력되는 중복 휴일을 중지 할 수있는 매우 비슷한 일을했다. 그렇게 VBA SQL에서 쿼리를했다 액세스에 있었고, 입력에 TEMPTABLE에 기록 :

     stCommandText = "SELECT " _
                        & "* " _
                        & "FROM " _
                        & "TableName a, " _
                        & "TableName b " _
                        & "WHERE " _
                        & "a.ID = b.ID " _
                        & "AND a.Startdate >= b.Startdate AND a.StartDate <= b.EndDate " _
                        & "AND a.AutoNo <> b.AutoNo "
    
  8. ==============================

    8.BTW - 당신이 고유 ID가없는 경우, 날짜에 대해 당신이 oracle..FYI하다 할 수있다

    BTW - 당신이 고유 ID가없는 경우, 날짜에 대해 당신이 oracle..FYI하다 할 수있다

    with date_ranges
    as
    (
    SELECT 
         rownum as pkey,
        date_ranges.*
    FROM  date_ranges
    ) 
    select 
    dr1.* 
    from 
    date_ranges dr1 , date_ranges dr2
    where  dr1.pkey > dr2.pkey
    AND dr1.end_dt >= dr2.start_dt 
    AND dr2.end_dt >= dr1.start_dt
    
  9. ==============================

    9.SQL은 = '(wba_task) WHERE (task_start_date <= "2016년 7월 13일"AND task_due_date> = "2016년 7월 25일") OR ( "2016년 7월 13일"BETWEEN task_due_date 및 "의 TASK_ID, task_start_date, task_due_date를 선택 2016년 7월 25일 ") ';

    SQL은 = '(wba_task) WHERE (task_start_date <= "2016년 7월 13일"AND task_due_date> = "2016년 7월 25일") OR ( "2016년 7월 13일"BETWEEN task_due_date 및 "의 TASK_ID, task_start_date, task_due_date를 선택 2016년 7월 25일 ") ';

    CodeIgniter의 쿼리는 다음과 같습니다.

    $fromdaysDate="2016-07-13";//changed date
    $todaysDate="2016-07-25";//changed date
    $this->db->select('task_id,task_start_date, task_due_date'); 
    $this->db->where('task_start_date <="'.date('Y-m-d', strtotime($fromdaysDate)).'"');
    $this->db->where('task_due_date >="'.date('Y-m-d', strtotime($todaysDate)).'"');    
    $this->db->or_where('task_due_date BETWEEN "'. date('Y-m-d', strtotime($fromdaysDate)). '" and "'. date('Y-m-d', strtotime($todaysDate)).'"');   
    $alltask=$this->db->get('wba_task')->result_array();
    echo $this->db->last_query();
    

    .... 모든 중복 데이터 형태로 데이터베이스를 얻을

  10. from https://stackoverflow.com/questions/4490553/detect-overlapping-date-ranges-from-the-same-table by cc-by-sa and MIT license