2014-04-15 3 views
-1

MySQL이 너무 오랫동안 FULL JOIN을 지원하지 않는다는 사실에 상당히 실망했습니다. (어째서?) 그리고 해결 방법으로 UNION을 사용해야합니다. 내가 다음 쿼리에 문제가 있다고 말했습니다. 기본적으로 내가 소유자에 할당 된 사양 컴퓨터의 목록을모호한 열 이름이있는 MySQL의 전체 조인 (공용)

컴퓨터

id userid owner cpu 
1 1  Jack 3.4 
2 1  Jack 3.4 
3 2  Sara 3.0 

모니터

id userid owner inch 
1 1  Jack 22  
2 1  Jack 22  
3 3  Mark 17  
4 4  Luke 32  

: 나는 예를 들어 두 개의 테이블이있다. 마찬가지로 나는 사양이있는 모니터 목록과 각 모니터가 소유자에게 할당되어 있습니다. 나는 성공적으로 쿼리 위의 결과를 얻을 수 있습니다

id userid owner cpu id userid owner inch 
1 1  Jack 3.4 1 1  Jack 22 
2 1  Jack 3.4 2 1  Jack 22 
3 2  Sara 3.0 null null  null null 
null null  null null 3 3  Mark 17 
null null  null null 4 4  Luke 32 

:

SELECT * FROM computers AS a 
LEFT OUTER JOIN monitors AS o on a.owner = o.owner 
UNION 
SELECT * FROM computers AS a 
RIGHT OUTER JOIN monitors AS o on a.owner = o.owner 

문제는 다음과 같습니다 나는이 결과에 소유자가이 두 테이블을 결합하려는

I
  1. 은 내 쿼리에서 유쾌한 성격을 사용하고 싶지 않습니다. 왜냐하면 효율적이지는 않지만 일부 특정 열만 필요하기 때문입니다.
  2. 두 테이블 모두 모호한 열 이름 (id, userid, owner)이 있으므로 예를 들어 소유자가 ORDER BY 할 수없는 것으로 보입니다. 난 내가 별칭을 사용한다는 것을 알고 있지만 나는 WHERE 문 사용해야 할
  3. 을 구현하는 방법을 이해하지 않지만 다시 지금에 있기 때문에 모호한 열 이름

의 그것을 구현하는 방법을 이해하지 않습니다 내가하고자 의사 쿼리에서 말한 요약 :

SELECT ID = 컴퓨터 WHERE CPU에서 a_owner 하지만 CPU AS A_ID, a_userid AS 사용자 ID, 소유자 AS 3.4

01 23,516,

UNION과 소유자가 가입 : b_id, b_userid AS 사용자 ID, b_owner AS 소유자로

SELECT ID는, 모니터로부터 AS b_inch 인치 WHERE 인치 =

22 시간 내 주셔서 감사합니다.

+0

나는 이것이 가상의 예이고 얼마가 아닌지 궁금해. 모든 레코드에서 사용자 아이디와 이름이 반복되는 데이터베이스 디자인이 좋지 않습니다. 그런 다음 사용자가 소유 한 모든 컴퓨터와 모니터를 결합합니다. 무엇 때문에? 모든 흥미있는 가능한 조합을 보려면? 주어진 쿼리를 사용하면 두 개의 잭 레코드가 아니라 네 개의 레코드를 얻을 수 있습니다. 모호한 열 이름은 한정자가 필요합니다. 이미 a.owner = o.owner에서 이것을 사용합니다. 그렇다면 문제는 어디에 있습니까? –

+0

내가 이미 말했듯이 내 것은 단지 예일뿐입니다. 내가 이런 말을 할 때,이 같은 구조를 가졌음을 말해줘. 디자인이 잘못되었다고 생각한다면 http://www.whmcs.com/을 비난해야합니다. 어쨌든 나를 믿어. 디자인은 절대적으로 훌륭하고 기능적입니다. 여기서 요점은 디자인이 얼마나 좋지/좋은지에 대해 토론하는 것이 아니라 FULL JOIN을 만드는 방법입니다. – user1274113

+0

오케이. 때로는 그러한 측면 발언이 도움이 될 수 있습니다. 나는 공격 할 뜻이 아니 었습니다 :-) 나는 대답을 올렸습니다. 희망이 당신의 모든 질문에 대답. –

답변

0

full outer join을 에뮬레이션하는 또 다른 방법은 하위 쿼리를 사용하여 전체 값 목록 (owner s)을 얻는 것입니다. 그런 다음 left outer join을 사용하여 다른 값을 가져옵니다. 귀하가 묘사 한 내용에 따라 :

select c.id as c_id, c.userid as c_userid, o.owner as owner, 
     m.id as m_id, m.user_id as m_userid, m.inch 
from (select owner from computers union 
     select owner from monitors 
    ) o left outer join 
    computers c 
    on o.owner = c.owner left outer join 
    monitors m 
    on o.owner = m.owner; 

그러나 이러한 쿼리는 생성되지 않습니다. "Jack"에 대해 네 가지 결과를 생성합니다.

편집 :

난 당신이, ownerid 일치 할 것으로 생각

user_id : 여기

select c.id as c_id, c.userid as c_userid, o.owner as owner, 
     m.id as m_id, m.user_id as m_userid, m.inch 
from (select owner, id, userid from computers union 
     select owner, id, userid from monitors 
    ) o left outer join 
    computers c 
    on o.owner = c.owner and o.userid = c.userid and o.id = c.id left outer join 
    monitors m 
    on o.owner = m.owner and o.userid = m.userid and o.id = m.id; 
+0

수정. 내 쿼리는 내가 말한 것을 반환하지 않습니다. 내 마음을 "새로 고침"하고 접근 방식을 이해하는 데 몇 분이 걸립니다. – user1274113

+0

예, 두 번째 쿼리는 내가 찾고있는 쿼리입니다. 그것은 작동합니다. 이제는 어떻게 작동하는지 완전히 이해할 수있는 몇 분이 필요합니다. 또한 어디에서/어떻게하면 C_cpu = 3.4 및 m_inch = 22 ** ** ORDER BY c_id **를 삽입 할 수 있는지를 이해할 수 있습니다. (여전히 의사를 사용하고 있습니다. - 물론 쿼리) – user1274113

+0

@ user1274113. . . 다른 질문을해야합니다. 댓글 섹션의 확장 된 질문과 대답은 눈살을 찌푸 리게됩니다. –

0

전체 외부 CPU = 3.4에 가입되어 인치 = 22 첫째 모든 얻을 컴퓨터를 연결하고 모니터에 가입 한 다음 모든 모니터를 가져 와서 컴퓨터에 가입하십시오. 주 테이블 기준은 WHERE 절에 있으며 외부 조인 기준은 ON 절에 있습니다.

SELECT a.userid, a.owner, a.id as computer_id, o.id as monitor_id, o.inch 
FROM computers AS a 
LEFT OUTER JOIN monitors AS o 
    ON a.owner = o.owner and a.userid = o.userid and o.inch = 22 
WHERE a.cpu = 3.4 
UNION 
SELECT o.userid, o.owner, a.id as computer_id, o.id as monitor_id, o.inch 
FROM monitors AS o 
LEFT OUTER JOIN computers AS a 
    ON a.owner = o.owner and a.userid = o.userid and a.cpu = 3.4 
WHERE o.inch = 22; 

에만 선택 먼저 찾지 레코드, 일치 컴퓨터가없는, 즉 모니터를 추가하지만, 가속화 될 수있다. 그런 다음 dbms에 많은 작업을 저장하는 UNION 대신 UNION ALL을 사용할 수 있습니다. 외부 조인 된 테이블의 Nullable이 아닌 C 럼을 선택하기 만하면됩니다. NULL이면 레코드가 외부 조인됩니다.

SELECT a.userid, a.owner, a.id as computer_id, o.id as monitor_id, o.inch 
FROM computers AS a 
LEFT OUTER JOIN monitors AS o 
    ON a.owner = o.owner and a.userid = o.userid and o.inch = 22 
WHERE a.cpu = 3.4 
UNION ALL 
SELECT o.userid, o.owner, a.id as computer_id, o.id as monitor_id, o.inch 
FROM monitors AS o 
LEFT OUTER JOIN computers AS a 
    ON a.owner = o.owner and a.userid = o.userid and a.cpu = 3.4 
WHERE o.inch = 22 and o.owner is null;