2017-09-30 7 views
0

다른 테이블에서 열을 선택하는 올바른 방법을 찾고 동시에 두 테이블을 포함하는 결과 하나를 표시하는 데 큰 어려움이 있습니다.오른쪽 조인/내부 조인/다중 선택 [MYSQL] 테이블 결과

첫 번째 테이블 :

id | times  | project_id | 
12 | 12.24  | 40   | 
13 | 13.22  | 40   | 
14 | 13.22  | 20   | 
15 | 12.22  | 20   | 
16 | 13.30  | 40   | 

두 번째 테이블 : 나는 PROJECT_ID = (40)에 대한 첫 번째 테이블의 모든 시간을 선택하고 두 번째 테이블에서이 시간에 가입 할 것으로 예상

id | times  | project_id | 
32 | 22.24  | 40   | 
33 | 23.22  | 40   | 
34 | 23.22  | 70   | 
35 | 22.22  | 70   | 
36 | 23.30  | 40   | 

같은 project_id = 40.

결과이 아래와 같이해야합니다 :

id | time  | time  | project_id | 
12 | 12.24  | 22.24  | 40   | 
13 | 13.22  | 23.22  | 40   | 
16 | 13.30  | 23.30  | 40   | 
+1

첫 번째 테이블의 '12.24'시간이 두 번째 테이블의 '22.24'시간에 합류하는 이유는 무엇입니까? 행의 순서에 따라? 이 작업이 어려운 이유는 테이블의 행에 암시 적 순서 나 순위가 지정되지 않기 때문입니다. 조인은 행 위치가 아닌 값을 일치시켜 작업합니다. –

+0

예 시간이 다릅니다. 행의 순서에 따라 선택하고 싶습니다. 그게 전부입니다. –

+0

"오른쪽 가입"은 여기에 필요하지 않습니다. –

답변

1

당신은 그렇지 않으면 당신은 잘못된 결과를 얻을 것이다 그 두 테이블 간의 UNION ALL를 사용해야합니다. 당신이 함께 모든 행이 있으면 당신은이 SQL Fiddle

MySQL을 5.6 스키마 설정에 아래 그림과 시연 등의 "이전 값"이월 변수를 사용할 수 있습니다 :

CREATE TABLE Table1 
    (`id` int, `times` decimal(6,2), `project_id` int) 
; 

INSERT INTO Table1 
    (`id`, `times`, `project_id`) 
VALUES 
    (12, 12.24, 40), 
    (13, 13.22, 40), 
    (14, 13.22, 20), 
    (15, 12.22, 20), 
    (16, 13.30, 40) 
; 


CREATE TABLE Table2 
    (`id` int, `times` decimal(6,2), `project_id` int) 
; 

INSERT INTO Table2 
    (`id`, `times`, `project_id`) 
VALUES 
    (32, 22.24, 40), 
    (33, 23.22, 40), 
    (34, 23.22, 70), 
    (35, 22.22, 70), 
    (36, 23.30, 40) 
; 

쿼리를 1 :

select 
     project_id, id, prev_time, times 
from (
    select 
      @row_num :=IF(@prev_value=d.project_id,@row_num+1,1) AS RowNumber 
     , d.* 
     , IF(@row_num %2 = 0, @prev_time, '') prev_time 
     , @prev_value := d.project_id 
     , @prev_time := times 
    from (
      select `id`, `times`, `project_id` from Table1 
      union all 
      select `id`, `times`, `project_id` from Table2 
     ) d 
    cross join (select @prev_value := 0, @row_num := 0) vars 
    order by d.project_id, d.times 
    ) d2 
where prev_time <> '' 

Results :

| project_id | id | prev_time | times | 
|------------|----|-----------|-------| 
|   20 | 14 |  12.22 | 13.22 | 
|   40 | 13 |  12.24 | 13.22 | 
|   40 | 32 |  13.30 | 22.24 | 
|   40 | 36 |  23.22 | 23.3 | 
|   70 | 34 |  22.22 | 23.22 | 

참고 :이 답변을 준비 할 때 MySQL doe snot은 현재 LEAD() 및 LAG() 함수를 지원합니다. MySQL이이를 지원할 때 그 접근법은 더 간단하고 효율적일 것입니다.

 
select 
     d.* 
from (
    select 
      d1.* 
     , LEAD(times,1) OVER(partition by project_id order by times ASC)next_time 
    from (
      select id, times, project_id from Table1 
      union all 
      select id, times, project_id from Table2 
     ) d1 
    ) d 
where next_time is not null