[SQL] 어떻게 FULL OUTER MySQL의에 가입 할까?
SQL어떻게 FULL OUTER MySQL의에 가입 할까?
나는 완전 외부의 MySQL에 가입하고 싶어. 이게 가능해? 전체 외부는 MySQL이 지원 가입되어 있습니까?
해결법
-
==============================
1.당신은 FULL은 MySQL을 JOINS 필요는 없지만, 확실히를 에뮬레이션 할 수 있습니다.
당신은 FULL은 MySQL을 JOINS 필요는 없지만, 확실히를 에뮬레이션 할 수 있습니다.
코드 샘플이 SO 질문에서 전사를 들어, 당신은 :
두 테이블 T1과, T2 :
SELECT * FROM t1 LEFT JOIN t2 ON t1.id = t2.id UNION SELECT * FROM t1 RIGHT JOIN t2 ON t1.id = t2.id
완전 외부 중복 행을 생성하지 것이다 작업을 가입 특별한 경우를 작품 위의 쿼리. 쿼리는 위의 쿼리 패턴에 의해 도입 중복 행을 제거하는 UNION 집합 연산자에 따라 달라집니다. 우리는 두 번째 쿼리에 대한 패턴을 방지 조인을 사용하여 중복 행을 도입하지 않도록 다음 두 가지를 결합하는 UNION ALL 집합 연산자를 사용할 수 있습니다. 완전 외부 중복 행을 반환 가입보다 일반적인 경우에, 우리는이 작업을 수행 할 수 있습니다
SELECT * FROM t1 LEFT JOIN t2 ON t1.id = t2.id UNION ALL SELECT * FROM t1 RIGHT JOIN t2 ON t1.id = t2.id WHERE t1.id IS NULL
-
==============================
2.파블로 산타 크루즈가 준 대답은 정확; 그러나, 경우에 사람이 페이지에서 발견 더 설명을하고자, 여기에 관한 자세한 세부 사항입니다.
파블로 산타 크루즈가 준 대답은 정확; 그러나, 경우에 사람이 페이지에서 발견 더 설명을하고자, 여기에 관한 자세한 세부 사항입니다.
우리는 다음과 같은 테이블이 있다고 가정 해 봅시다 :
-- t1 id name 1 Tim 2 Marta -- t2 id name 1 Tim 3 Katarina
내부는 다음과 같이 조인
SELECT * FROM `t1` INNER JOIN `t2` ON `t1`.`id` = `t2`.`id`;
우리에게 다음과 같이 두 테이블에 표시 만 기록을 얻을 것이다 :
1 Tim 1 Tim
내부는 명시 적으로 양방향이기 때문에 (왼쪽 또는 오른쪽처럼) 방향이없는 조인 - 우리는 양쪽에 일치를 필요로합니다.
외부 조인, 다른 한편으로는, 다른 테이블에서 일치가 없을 수 기록을 찾아 내기위한 것입니다. 따라서, 당신은 누락 된 기록을 가질 수 조인의 어느 쪽 지정해야합니다.
왼쪽은 가입 및 오른쪽은 왼쪽 외부 조인과 오른쪽 외부 조인에 대한 속기 있습니다 가입; 외부 내부 조인 대 조인의 개념을 강화하기 위해 아래 나는 그들의 전체 이름을 사용합니다.
A는 외부과 같이 가입 왼쪽 :
SELECT * FROM `t1` LEFT OUTER JOIN `t2` ON `t1`.`id` = `t2`.`id`;
... 관계없이 다음과 같이 오른쪽 테이블에 일치하는이 있는지 여부의 우리에게 왼쪽 테이블의 모든 레코드를 얻을 것입니다 :
1 Tim 1 Tim 2 Marta NULL NULL
오른쪽 바깥이 같은 조인
SELECT * FROM `t1` RIGHT OUTER JOIN `t2` ON `t1`.`id` = `t2`.`id`;
... 관계없이 다음과 같이, 왼쪽 테이블에 일치하는이 있는지 여부의 우리에게 오른쪽 테이블의 모든 레코드를 얻을 것입니다 :
1 Tim 1 Tim NULL NULL 3 Katarina
전체 외부는 다른 테이블에 일치하는이 있는지 여부 일치가없는 양쪽에 null로, 두 테이블에서 우리에게 모든 레코드를 줄 것이다 가입 할 수 있습니다. 결과는 다음과 같을 것이다 :
1 Tim 1 Tim 2 Marta NULL NULL NULL NULL 3 Katarina
파블로 산타 크루즈 지적하지만, MySQL은이 기능을 지원하지 않습니다. 우리는 참여와 오른쪽과 같이 조인 왼쪽의 UNION을 수행하여 에뮬레이션 할 수 있습니다 :
SELECT * FROM `t1` LEFT OUTER JOIN `t2` ON `t1`.`id` = `t2`.`id` UNION SELECT * FROM `t1` RIGHT OUTER JOIN `t2` ON `t1`.`id` = `t2`.`id`;
당신은 "이러한 쿼리 모두 다음, 서로의 상단에 결과를 스택 실행"을 의미로 UNION 생각할 수 있습니다; 행 중 일부는 첫 번째 쿼리와 두 번째의 일부에서 올 것이다.
팀이 여기에 쿼리에 모두 표시,하지만 한 번 UNION의 결과는리스트 그를 : MySQL의에서 UNION 정확한 중복을 제거 것이라는 점을 주목해야한다. 내 데이터베이스 전문가의 동료는이 동작에 의존해서는 안 느낀다. 그래서 그것에 대해 더 명시 적으로, 우리는 두 번째 쿼리에 WHERE 절을 추가 할 수 있습니다 :
SELECT * FROM `t1` LEFT OUTER JOIN `t2` ON `t1`.`id` = `t2`.`id` UNION SELECT * FROM `t1` RIGHT OUTER JOIN `t2` ON `t1`.`id` = `t2`.`id` WHERE `t1`.`id` IS NULL;
당신이 어떤 이유로 중복을보고 싶어 경우 반면에, 당신은 UNION ALL을 사용할 수 있습니다.
-
==============================
3.통합 쿼리를 사용하여 중복을 제거하고이 완전 외부의 동작은 중복 제거 결코 가입보다 다른 것입니다 :
통합 쿼리를 사용하여 중복을 제거하고이 완전 외부의 동작은 중복 제거 결코 가입보다 다른 것입니다 :
[Table: t1] [Table: t2] value value ------- ------- 1 1 2 2 4 2 4 5
이 조인 완전 외부의 예상 된 결과입니다 :
value | value ------+------- 1 | 1 2 | 2 2 | 2 Null | 5 4 | Null 4 | Null
이 왼쪽 사용한 결과이며, 바로 노동 조합에 가입 :
value | value ------+------- Null | 5 1 | 1 2 | 2 4 | Null
[SQL 바이올린]
내 추천 검색어는 다음과 같습니다
select t1.value, t2.value from t1 left outer join t2 on t1.value = t2.value union all -- Using `union all` instead of `union` select t1.value, t2.value from t2 left outer join t1 on t1.value = t2.value where t1.value IS NULL
예상 된 결과와 동일하다 위의 쿼리의 결과 :
value | value ------+------- 1 | 1 2 | 2 2 | 2 4 | NULL 4 | NULL NULL | 5
[SQL 바이올린]
내가 시각화 및 수학에 가입 완전 외부에서 오는 다른 솔루션을 추가하기로 결정, 그것은 좋은 것은 아닙니다 위와 같지만 더 읽기가 :
-- (t1 ∩ t2): all in both t1 and t2 select t1.value, t2.value from t1 join t2 on t1.value = t2.value union all -- And plus -- all in t1 that not exists in t2 select t1.value, null from t1 where not exists( select 1 from t2 where t2.value = t1.value) union all -- and plus -- all in t2 that not exists in t1 select null, t2.value from t2 where not exists( select 1 from t1 where t2.value = t1.value)
[SQL 바이올린]
-
==============================
4.MySQL은 구문을 FULL-외부-가입이 없습니다. 당신은 JOIN 모두 LEFT를 수행하여 에뮬레이션해야하고 RIGHT follows-로 가입하기
MySQL은 구문을 FULL-외부-가입이 없습니다. 당신은 JOIN 모두 LEFT를 수행하여 에뮬레이션해야하고 RIGHT follows-로 가입하기
SELECT * FROM t1 LEFT JOIN t2 ON t1.id = t2.id UNION SELECT * FROM t1 RIGHT JOIN t2 ON t1.id = t2.id
그러나 MySQL은 또한 RIGHT JOIN 구문을 가지고 있지 않습니다. MySQL의 외측의 가입 간소화에 따르면, 오른쪽은 왼쪽 등가 변환 조인 쿼리로부터 ON 절에서 T1 및 T2를 전환하여 가입. 따라서, MySQL의 쿼리 최적화는 다음에 원래의 쿼리를 변환 -
SELECT * FROM t1 LEFT JOIN t2 ON t1.id = t2.id UNION SELECT * FROM t2 LEFT JOIN t1 ON t2.id = t1.id
지금, 당신은 가입시 - 술어 ON 절에 조인하기 전에-조건 또는 AND 조건입니다 WHERE 절, 같은 조건이있는 경우 다음 말씀이 있으므로 원래 쿼리를 작성에 전혀 해가 없지만, 당신은 악마를 살펴 할 수 있습니다; 이는 세부 사항에 있습니다.
MySQL의 쿼리 최적화가 널 거부하는 경우 정기적으로 조건을 확인합니다. 당신이 할 경우 이제, RIGHT,하지만 T1에서 컬럼에 술어가, 당신은 널 거부 시나리오에 실행의 위험에 노출 될 수있는 WHERE에 가입.
예를 들어, 다음 쿼리 -
SELECT * FROM t1 LEFT JOIN t2 ON t1.id = t2.id WHERE t1.col1 = 'someValue' UNION SELECT * FROM t1 RIGHT JOIN t2 ON t1.id = t2.id WHERE t1.col1 = 'someValue'
쿼리 Optimizer-에 의해 다음에 번역됩니다
SELECT * FROM t1 LEFT JOIN t2 ON t1.id = t2.id WHERE t1.col1 = 'someValue' UNION SELECT * FROM t2 LEFT JOIN t1 ON t2.id = t1.id WHERE t1.col1 = 'someValue'
테이블의 순서가 변경되었습니다 만, 술어는 여전히 T1에 적용되지만, T1은 'ON'절에 지금 그래서. t1.col1는 NOT의 NULL로 정의 된 경우 열은,이 쿼리는 널 거부됩니다.
상관은 외부 조인 (왼쪽, 오른쪽, 전체) 즉 널 거부 변환된다 MySQL이 내부 조인.
따라서 당신이 예상 할 수있는 결과는 MySQL이 반환하는 것과 전혀 다를 수 있습니다. 당신은 MySQL을의 권리와 자사의 버그가 가입 생각하지만, 그게 전부하지 못했습니다 수 있습니다. 그 얼마나 MySQL의 쿼리 최적화 작동합니다. 개발자-의 충전 그가 쿼리를 작성하는 경우 이러한 미묘한 차이에주의를 지불해야 그래서.
-
==============================
5.SQLite는 당신은이 작업을 수행해야합니다 :
SQLite는 당신은이 작업을 수행해야합니다 :
SELECT * FROM leftTable lt LEFT JOIN rightTable rt ON lt.id = rt.lrid UNION SELECT lt.*, rl.* -- To match column set FROM rightTable rt LEFT JOIN leftTable lt ON lt.id = rt.lrid
-
==============================
6.중복 된 값이있는 경우가 의미를 따르지 않기 때문에 위의 답변 중 어느 것도 실제로 정확하지 않습니다.
중복 된 값이있는 경우가 의미를 따르지 않기 때문에 위의 답변 중 어느 것도 실제로 정확하지 않습니다.
등 (이 중복에서)와 같은 쿼리 :
SELECT * FROM t1 FULL OUTER JOIN t2 ON t1.Name = t2.Name;
올바른 것과 동일합니다 :
SELECT t1.*, t2.* FROM (SELECT name FROM t1 UNION -- This is intentionally UNION to remove duplicates SELECT name FROM t2 ) n LEFT JOIN t1 ON t1.name = n.name LEFT JOIN t2 ON t2.name = n.name;
당신이 NULL 값을 갖는 일 (필요할 수도 있음)이 필요한 경우, NULL 안전 비교 연산자, <=> 아니라 = 이상을 사용합니다.
-
==============================
7.더 명확하게하기 위해 shA.t의 쿼리를 수정 :
더 명확하게하기 위해 shA.t의 쿼리를 수정 :
-- t1 left join t2 SELECT t1.value, t2.value FROM t1 LEFT JOIN t2 ON t1.value = t2.value UNION ALL -- include duplicates -- t1 right exclude join t2 (records found only in t2) SELECT t1.value, t2.value FROM t1 RIGHT JOIN t2 ON t1.value = t2.value WHERE t2.value IS NULL
-
==============================
8.다음과 같은 작업을 수행 할 수 있습니다 :
다음과 같은 작업을 수행 할 수 있습니다 :
(SELECT * FROM table1 t1 LEFT JOIN table2 t2 ON t1.id = t2.id WHERE t2.id IS NULL) UNION ALL (SELECT * FROM table1 t1 RIGHT JOIN table2 t2 ON t1.id = t2.id WHERE t1.id IS NULL);
-
==============================
9.당신이 솔루션을 가입 크로스에 대해 뭐라고 뭐라고?
당신이 솔루션을 가입 크로스에 대해 뭐라고 뭐라고?
SELECT t1.*, t2.* FROM table1 t1 INNER JOIN table2 t2 ON 1=1;
-
==============================
10.
SELECT a.name, b.title FROM author AS a LEFT JOIN book AS b ON a.id = b.author_id UNION SELECT a.name, b.title FROM author AS a RIGHT JOIN book AS b ON a.id = b.author_id
-
==============================
11.또한 가능하지만, 당신은 선택의 동일한 필드 이름을 언급해야한다.
또한 가능하지만, 당신은 선택의 동일한 필드 이름을 언급해야한다.
SELECT t1.name, t2.name FROM t1 LEFT JOIN t2 ON t1.id = t2.id UNION SELECT t1.name, t2.name FROM t2 LEFT JOIN t1 ON t1.id = t2.id
-
==============================
12.나는 응답을 수정하고, 작품의 모든 행을 포함 (Pavle Lekic의 응답 기준)
나는 응답을 수정하고, 작품의 모든 행을 포함 (Pavle Lekic의 응답 기준)
( SELECT a.* FROM tablea a LEFT JOIN tableb b ON a.`key` = b.key WHERE b.`key` is null ) UNION ALL ( SELECT a.* FROM tablea a LEFT JOIN tableb b ON a.`key` = b.key where a.`key` = b.`key` ) UNION ALL ( SELECT b.* FROM tablea a right JOIN tableb b ON b.`key` = a.key WHERE a.`key` is null );
-
==============================
13.대답:
대답:
SELECT * FROM t1 FULL OUTER JOIN t2 ON t1.id = t2.id;
다음과 같이 재현 할 수 :
SELECT t1.*, t2.* FROM (SELECT * FROM t1 UNION SELECT name FROM t2) tmp LEFT JOIN t1 ON t1.id = tmp.id LEFT JOIN t2 ON t2.id = tmp.id;
노동 조합 또는 UNION ALL 응답을 사용하면 기본 테이블이 중복 된 항목이 가장자리의 경우 적용되지 않습니다.
설명:
노동 조합 또는 UNION ALL 커버 할 수없는 가장자리 경우가 있습니다. 이 FULL OUTER 조인을 지원하지 않기 때문에 우리는 MySQL의에서이 작업을 테스트 할 수 없습니다, 그러나 우리는 그것을 지원하지 않습니다 데이터베이스에이를 설명 할 수 있습니다 :
WITH cte_t1 AS ( SELECT 1 AS id1 UNION ALL SELECT 2 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 6 ), cte_t2 AS ( SELECT 3 AS id2 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 6 ) SELECT * FROM cte_t1 t1 FULL OUTER JOIN cte_t2 t2 ON t1.id1 = t2.id2; This gives us this answer: id1 id2 1 NULL 2 NULL NULL 3 NULL 4 5 5 6 6 6 6 6 6 6 6
노조 솔루션 :
SELECT * FROM cte_t1 t1 LEFT OUTER JOIN cte_t2 t2 ON t1.id1 = t2.id2 UNION SELECT * FROM cte_t1 t1 RIGHT OUTER JOIN cte_t2 t2 ON t1.id1 = t2.id2
잘못된 답을 제공합니다 :
id1 id2 NULL 3 NULL 4 1 NULL 2 NULL 5 5 6 6
UNION에서 ALL 솔루션 :
SELECT * FROM cte_t1 t1 LEFT OUTER join cte_t2 t2 ON t1.id1 = t2.id2 UNION ALL SELECT * FROM cte_t1 t1 RIGHT OUTER JOIN cte_t2 t2 ON t1.id1 = t2.id2
또한 올바르지 않습니다.
id1 id2 1 NULL 2 NULL 5 5 6 6 6 6 6 6 6 6 NULL 3 NULL 4 5 5 6 6 6 6 6 6 6 6
이 쿼리 반면 :
SELECT t1.*, t2.* FROM (SELECT * FROM t1 UNION SELECT name FROM t2) tmp LEFT JOIN t1 ON t1.id = tmp.id LEFT JOIN t2 ON t2.id = tmp.id;
다음을 제공합니다 :
id1 id2 1 NULL 2 NULL NULL 3 NULL 4 5 5 6 6 6 6 6 6 6 6
순서는 다르지만, 그렇지 않으면 정답과 일치합니다.
-
==============================
14.전체에 가입 말합니다 표준 SQL 내부 행 조합에 널 (null) 조합 널 (null)에 의해 확장 모든 권리 테이블 행에 의해 확장 된 모든 타의 추종을 불허하는 왼쪽 테이블 행을 조인. 즉 내부 행 조합 왼쪽에있는 모든 행에 합류하지만 내부는 노동 조합에 오른쪽 가입의 모든 행에 합류하지만 내부하지가 가입에 가입 할 수 있습니다.
전체에 가입 말합니다 표준 SQL 내부 행 조합에 널 (null) 조합 널 (null)에 의해 확장 모든 권리 테이블 행에 의해 확장 된 모든 타의 추종을 불허하는 왼쪽 테이블 행을 조인. 즉 내부 행 조합 왼쪽에있는 모든 행에 합류하지만 내부는 노동 조합에 오른쪽 가입의 모든 행에 합류하지만 내부하지가 가입에 가입 할 수 있습니다.
즉 모든 오른쪽에 조인 행에 가입하지 내부의 행 조합에 가입 떠났다. 당신은 당신의 내면 다음 특정 권리 테이블 컬럼에 널 (null)을 가질 수 없습니다 결과에 가입 알고있는 경우 또는 "오른쪽 행에없는 내부가 조인에 참여"바로 확장 상태에와에 조인 행은 그 열은 null입니다.
즉 유사 권리 행에 가입 노동 조합에 모든 적절한 왼쪽을 가입 할 수 있습니다.
의 차이 무엇입니까에서와 "외부 조인", "내부 조인"?
from https://stackoverflow.com/questions/4796872/how-to-do-a-full-outer-join-in-mysql by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] SQL Server의 '피봇'를 사용하여 열을 변환 행 (0) | 2020.03.05 |
---|---|
[SQL] GROUP BY에서 LIMIT를 사용하면 그룹 별 N 결과를 얻으려면? (0) | 2020.03.05 |
[SQL] 효율적으로 SQL 서버에 열을 행으로 변환 (0) | 2020.03.05 |
[SQL] SQL 주입은 무엇인가? [복제] (0) | 2020.03.05 |
[SQL] 동적 열 수로 MySQL의 피봇 행 (0) | 2020.03.05 |