2012-08-31 2 views
1

왼쪽 테이블의 날짜 값이 오른쪽 테이블의 시간 슬롯에 속하는 두 개의 테이블로 조인을 작성하려고합니다. 따라서, 예를 들어 내가있는 경우 :역사적인 타임 라인이있는 테이블 조인

TABLE A      TABLE B 
ID TIMESTMP    ID TIMESMTP    VALUE 
1  8/31/2012 2:00 PM  1  8/30/2012 4:00 AM A 
2  8/29/2012 3:00 PM  1  8/31/2012 1:00 PM B 
3  7/04/2012 5:00 AM  1  8/31/2012 3:00 PM C 
          2  8/20/2012 1:00 PM A 

결과는 같아야합니다

TABLE C      
ID TIMESTMP    VALUE 
1  8/31/2012 2:00 PM B 
2  8/29/2012 3:00 PM A  
3  7/04/2012 5:00 AM null 

내가 < 여전히 테이블 A의 타임 스탬프입니다 최대 타임 스탬프와 테이블 B에서 해당 레코드를 찾으려면 일치하는 id (외부 조인)가 없거나 A에 시간 소인 B <에 시간 소인이 없으면 널을 리턴해야합니다.

감사합니다. 이 SQL 서버 인 경우 나는이 외부로 달성 될 수있다 적용 생각

SELECT b.value, a.* 
    FROM table_a a 
    LEFT OUTER JOIN (
    SELECT id, timestmp, 
      lead(timestmp) over(PARTITION BY id ORDER BY timestmp) AS next_timestmp, 
      value FROM table_b 
    ) b 
    ON a.id = b.id 
    AND (a.timestmp >= b.timestmp AND (a.timestmp < b.timestmp OR b.timestmp IS NULL)) 

답변

1

"="을 사용하지 않고 조인으로 표현할 수 있습니다. 그러나 도움이 될 것은 각 행에 다음 시간 소인을 갖는 것입니다.

select a.id, a.timestmp, b.value 
from A left outer join 
    (select b.*, 
      lead(timesmtp) over (partition by id order by timesmtp) as nextTS 
     from B 
    ) b 
    on a.id = b.id and 
     a.timestmp >= b.timesmtp and 
     a.timestmp < coalesce(nextTS, a.timestmp) 
+0

나는이 아이디어를 정말 좋아합니다. 나는 lead() 함수에 대해 몰랐다. 슈퍼 편리한. 그러나,이 조인을 사용하면 내 결과 세트가 줄어 듭니다 (오른쪽 외부 조인을 수행 할 때조차도). – Paul

+0

왼쪽 외부 조인을 시도해야합니다. . . 그런 식으로 A의 모든 것을 유지하게됩니다. –

+0

죄송합니다. 내 머리를 거꾸로 가졌습니다. 네가 맞아, 왼쪽 외부 조인은 내가 한 일을 나에게 준다. 나는 조금 다르게 끝내었지만 lead() 함수가 핵심이었다. – Paul

1

: 여기 UPDATE

은 고든 리노 프에 의해 제안 내가 리드()를 사용하여 갔다 솔루션입니다

SELECT A.id, A.timestmp, B.value FROM A OUTER APPLY (SELECT TOP 1 value FROM B WHERE id = A.id AND timesmtp < A.timestmp ORDER BY timesmtp DESC) B 
+0

나는 그것이 수치 인, 생각하지 않는다, 즉 깔끔한 때문에 : 리드() 함수는 편리 할 것입니다. – podiluska

+0

질문에 Oracle 태그가 지정되었습니다. –

+0

죄송합니다. –

2
즉,
+1

오라클은 진술 문 종료 문자 **를 필요로합니다 ** 문 앞에 * 아니요 * 문 앞에 –

0
select t.ID, t.Timestamp,B.Value 
from 
(
select A.ID, A.Timestamp, (SELECT max(B.TimeStamp) 
    FROM B where (B.Timestamp<A.Timestamp) and (B.id=A.Id) 
    ) max_date 

from A 
) t 
left join B on (t.max_date=B.TimeStamp) and (t.Id=B.ID)