복붙노트

[SQL] SQL 시간 간격 중복으로 행을 찾을 수있는 간단하고 효율적인 방법은 무엇입니까?

SQL

SQL 시간 간격 중복으로 행을 찾을 수있는 간단하고 효율적인 방법은 무엇입니까?

나는 시작 시간과 종료 시간 필드에 모두 두 개의 테이블이있다. 나는 시간 간격이 교차하는 두 번째 테이블에서 첫 번째 테이블의 각 행에 대해 찾을 수있는 모든 행을해야합니다.

예를 들면 :

           <-----row 1 interval------->
<---find this--> <--and this--> <--and this-->

제발 문구 당신은 SQL WHERE 절의 형태로 답하고, 두 번째 테이블의 종료 시간은 NULL이 될 수있는 경우를 고려한다.

대상 플랫폼은 SQL 서버 2005이지만, 다른 플랫폼의 솔루션도 관심이있을 수 있습니다.

해결법

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

    1.

    SELECT * 
    FROM table1,table2 
    WHERE table2.start <= table1.end 
    AND (table2.end IS NULL OR table2.end >= table1.start)
    
  2. ==============================

    2.

    select * from table_1 
    right join 
    table_2 on 
    (
    table_1.start between table_2.start and table_2.[end]
    or
    table_1.[end] between table_2.start and table_2.[end]
    or
    (table_1.[end] > table_2.start and table_2.[end] is null)
    )
    

    편집 : 좋아, 내 솔루션을하지 않습니다, 그것은 똥 perfoms. 은 "여기서"솔루션은 빠른 14 배이다. 죄송합니다 ...

    일부 통계 : ~와 DB에서 실행되는 표 1과 2 (NO 색인), 각 행의 시작과 끝 사이에 2 일 간격을 가진 SQLSMSE에서 2 분 동안 실행 모두 65000 개 기록 (대기에 인내심을 가지고 있지 않습니다 )

    가입 사용 : 8356 행 2 분

    여기서 사용 : 115436 행 2 분

  3. ==============================

    3.당신이 역에서 작업을 시작할 때까지의 사운드는 매우 복잡합니다. 내가 유일하게 좋은 예 (중복이없는 경우)를 그림 아래! CONDA 또는 condB가 TRUE 인 경우 우리가 그 역가는, 그래서 사람들이 개 간단한 조건에 의해 정의 된, 우리는 중첩 범위가 없습니다 : NOT CONDA AND NOT CondB는, 우리의 경우 그냥 표지판을 반전 (> 된 <=)

    당신이 역에서 작업을 시작할 때까지의 사운드는 매우 복잡합니다. 내가 유일하게 좋은 예 (중복이없는 경우)를 그림 아래! CONDA 또는 condB가 TRUE 인 경우 우리가 그 역가는, 그래서 사람들이 개 간단한 조건에 의해 정의 된, 우리는 중첩 범위가 없습니다 : NOT CONDA AND NOT CondB는, 우리의 경우 그냥 표지판을 반전 (> 된 <=)

    /*
    |--------| A                             \___  CondA: b.ddStart >  a.ddEnd
                |=========| B                /      \____ CondB:  a.ddS >  b.ddE
                              |+++++++++| A         /
    */
    --DROP TABLE ran
    create table ran ( mem_nbr int, ID int, ddS date, ddE date)
    insert ran values  
    (100, 1,  '2012-1-1','2012-12-30'),    ----\ ovl
    (100, 11, '2012-12-12','2012-12-24'),  ----/
    (100, 2, '2012-12-31','2014-1-1'),
    (100, 3, '2014-5-1','2014-12-14') ,
    
    (220, 1, '2015-5-5','2015-12-14') ,    ---\ovl
    (220, 22, '2014-4-1','2015-5-25') ,    ---/
    (220, 3, '2016-6-1','2016-12-16')  
    
    select  DISTINCT a.mem_nbr ,  a.* , '-' [ ], b.dds, b.dde, b.id 
    FROM ran a
    join ran b  on  a.mem_nbr = b.mem_nbr          -- match by mem#
                   AND     a.ID <> b.ID            -- itself
                      AND     b.ddS <= a.ddE        -- NOT    b.ddS >  a.ddE       
                      AND     a.ddS <= b.ddE        -- NOT    a.ddS >  b.ddE   
    
  4. ==============================

    4.그리고 무엇을, 당신은 70m + 행 분 정밀도에 이러한 중복을 분석하려면? 내가 만들 수있는 유일한 해결책은 자신이 가입을위한 시간 차원 테이블이었다

    그리고 무엇을, 당신은 70m + 행 분 정밀도에 이러한 중복을 분석하려면? 내가 만들 수있는 유일한 해결책은 자신이 가입을위한 시간 차원 테이블이었다

    다른 중복 취급 두통이되었다 .. 및 처리 비용이 경우 천문학적

  5. from https://stackoverflow.com/questions/117962/what-is-a-simple-and-efficient-way-to-find-rows-with-time-interval-overlaps-in-s by cc-by-sa and MIT license