2014-10-02 1 views
0

MySQL의 멍청한 놈 질문 :활동의 상관 관계 쿼리 사용하여 MySQL의

내가 두 엔티티 "foo"와 "bar"내가 상관 할의 활동이있다. 특히, 주어진 "foo"개체와 같은 시간에 "bar"개체 중 어떤 개체가 활성 상태인지 결정하고 싶습니다. 이를 위해

, 나는 두 개의 테이블과 간단한 MySQL 데이터베이스를 설정 한 :

select * from foo; 
+------+---------------------+---------------------+ 
| id | arrive    | depart    | 
+------+---------------------+---------------------+ 
| 1 | 2014-10-01 08:00:00 | 2014-10-01 09:00:00 | 
| 1 | 2014-10-01 10:00:00 | 2014-10-01 11:00:00 | 
| 1 | 2014-10-01 12:00:00 | 2014-10-01 13:00:00 | 
| 2 | 2014-10-01 09:00:00 | 2014-10-01 10:00:00 | 
| 2 | 2014-10-01 12:00:00 | 2014-10-01 13:00:00 | 
+------+---------------------+---------------------+ 

select * from bar; 

+------+---------------------+---------------------+ 
| id | start    | end     | 
+------+---------------------+---------------------+ 
| 1 | 2014-10-01 08:05:00 | 2014-10-01 08:55:00 | 
| 1 | 2014-10-01 09:05:00 | 2014-10-01 09:55:00 | 
| 1 | 2014-10-01 11:05:00 | 2014-10-01 11:55:00 | 
| 2 | 2014-10-01 11:05:00 | 2014-10-01 11:55:00 | 
| 2 | 2014-10-01 12:05:00 | 2014-10-01 12:55:00 | 
| 2 | 2014-10-01 07:05:00 | 2014-10-01 07:55:00 | 
| 3 | 2014-10-01 08:05:00 | 2014-10-01 08:55:00 | 
| 3 | 2014-10-01 10:05:00 | 2014-10-01 10:55:00 | 
| 3 | 2014-10-01 12:05:00 | 2014-10-01 12:55:00 | 
+------+---------------------+---------------------+ 

없이이 "도착"과 "시작"열 "의 활동 기간의 시작을 나타내고, 말 depart "및"end "열은 각 마침표를 나타내며 id 열은 각 개체의 고유 식별자입니다.

첫 번째 단계로 foo의 각 활동 기간에 대해 동일한 기간 동안 활성화 된 막대 객체 세트를 결정하고 싶습니다. 푸 # 1에 대한 상기 샘플 데이터로부터

: 8시 9:00 사이 (즉 푸 번호 제 활동 기간 1) 바 # 1 바 # 3 10:00 사이 모두 활성 12 시부 터 13 시까 지 12 시부 터 13시 사이의 막대 번호 # 2와 막대 번호 # 3 사이의 숫자는 입니다.

일단이 세트가 결정되면, 교차점을 결정할 수 있습니다. (예를 들어 bar # 3은 foo object # 1과 같은 시간에 활성화 된 유일한 bar 객체입니다).

이 결과를 반환하는 쿼리를 개발하려고합니다. 이상적으로이 쿼리는 전체 데이터베이스를 분석하여 하나의 "foo"id와 하나의 "bar"id가 포함 된 행을 검색합니다. 출발점으로

, 내가 foo는 활동의 각 기간 동안 활성화 된 바 모든 개체 식별 할 수 있도록 쿼리를 내놓았다 : 그러나

SELECT foo.id, 
     bar.id 
FROM foo 
LEFT JOIN bar 
ON bar.start >= foo.arrive 
AND bar.end <= foo.depart; 

을, 나는 당장은 아무 생각이 없다 . 상관 관계가있는 하위 쿼리는 유용 할 것으로 보이지만 오류없이 공식화하는 것은별로 행운이 없습니다. 그게 올바른 접근법인지 확실하지 않습니다.

제안 사항?

+0

원하는 출력이 어떻게 표시되는지 예를 들려 줄 수 있습니까? – Arun

+0

검색어는 foo의 마침표 사이에서 시작하고 끝나는 막대 만 고려합니다.부분적으로 겹칠 수 없습니까? – 1010

+0

Arun 내가 찾고있는 출력은 단순히 foo ID와 일치하는 바 ID입니다. Ollie Jones의 대답은 그것을 제쳤다. @ 1010 아니요, 특히 겹치는 모든 사례를 제외하고 싶습니다. – swarga

답변

0

지금까지 살펴본 바와 같이 JOIN 쿼리가 정확합니다. 그것은 (도착 - 출발) 간격 내에 완전히 포함 된 (시작 - 끝) 간격을 선택합니다. JOIN이 올바른 선택입니다. 결과 집합에 invervals 추가

는 파악이 쉬워집니다 :

SELECT foo.id AS fooid, arrive, depart, 
     bar.id AS barid, start, end 
    FROM foo 
    LEFT JOIN bar 
       ON bar.start >= foo.arrive 
      AND bar.end <= foo.depart 

가 여기에 그것을 보여주는 SQL 바이올린입니다. http://sqlfiddle.com/#!2/68b7dc/3/0

그런 다음 고유 한 "foo"항목 수를 계산하고 고유 조합 수를 계산하십시오. 그런 다음 함께 참여하면 원하는 결과를 얻을 수 있습니다. http://sqlfiddle.com/#!2/ed5ac/5/0

SELECT a.fooid, b.barid 
    FROM (
     SELECT COUNT(*) AS count, 
      id AS fooid 
     FROM foo 
     GROUP BY id 
     ) AS a 
    JOIN (
     SELECT COUNT(*) AS count, 
       foo.id AS fooid, 
       bar.id AS barid 
     FROM foo 
     LEFT JOIN bar 
        ON bar.start >= foo.arrive 
        AND bar.end <= foo.depart 
     GROUP BY foo.id, bar.id 
     ) AS b ON a.count=b.count AND a.fooid = b.fooid 

나는 이것이 당신이 원하는대로한다고 생각합니다. 그러나 더 철저한 설명 없이는 확신하기 어렵습니다.

+0

동의합니다. 나는 조인을 바꿔서 술집이없는 술집을 포함하도록 왼쪽 조인을했습니다. – 1010