2011-09-26 3 views
1

유니온 고유를 사용하는 동안 하위 쿼리의 결과 순서가 보존되도록하고 싶습니다. 유니온을 수행하는 동안 중복을 필터링하려면 "유니언 고유"가 필요합니다. 예를 들어MySQL - "유니언 고유"구문을 사용하는 동안 하위 쿼리의 레코드 순서 유지

는 : 순서에 의해 반환 내가 이것을 실행하면, 나는 서브 쿼리에서 주문 레코드 (오름차순 [columnA3]에 의해 TABLEA 순서에서 columnA1, columnA2 선택) 것을 기대하고

select columnA1, columnA2 from tableA order by [columnA3] asc 
    union distinct 
    select columnB1, columnB2 from tableB 

(먼저 온다 by columnA3 asc) 그 다음에 tableB의 값이옵니다.

다른 더미 열을 추가 할 수 없다고 가정하고 있는데, 이렇게하면 유니온을 작동하지 않게 할 수 있기 때문입니다. 그래서,이 작동하지 않습니다

UNION은 별도의 세트에서-속는를 해제하지만, 세트

또는

내에서하지 않는 것이

select column1, column2 from 
(select column1, column2, 1 as ORD from tableA order by [columnA3] asc 
union distinct 
select column1, column2, 2 as ORD from tableB 
) order by ORD 
+0

왜 더미 열을 추가 할 수 없습니까? 그게 뭐가 잘못 되었 니? – Karolis

+0

@Karolis tableA 및 tableB의 레코드의 고유성은 {column1 쌍을 기준으로 설정됩니다. column2}. 순서를 보장하기 위해 더미 열을 추가하면 고유하지 않게됩니다. – user965692

+0

그래, 너는 케이드의 대답에서 무엇을하려고하는지 이해했다. – Karolis

답변

1
select column1, column2 from 
(select column1, column2, 1 as ORD from tableA 
union distinct 
select tableB.column1, tableB.column2, 2 as ORD from tableB 
    LEFT JOIN tableA 
     ON tableA.column1 = tableB.column1 AND tableA.column2 = tableB.column2 
    WHERE tableA.column1 IS NULL 
) order by ORD 

참고 : 기본적으로

select column1, column2 from 
(select column1, column2, 1 as ORD from tableA 
union distinct 
select column1, column2, 2 as ORD from tableB 
WHERE (column1, column2) NOT IN (SELECT column1, column2 from tableA) 
) order by ORD 
+0

'주문 순서'노조에는 아무런 의미가 없다. 노조 밖에 넣어야한다. – Karolis

+0

@Karolis - 죄송합니다, 그의 예에서 나온 것입니다. –

+0

@CadeRoux - 불행히도 다른 테이블이 너무 커서 성능 병목 현상을 일으키기 때문에 왼쪽 결합을 수행 할 수 없습니다.사실, 그건 내 첫 접근 이었지만 너무 느립니다. – user965692

3

, MySQL은 "Union distinct"구문을 사용하는 동안 하위 쿼리의 레코드 순서를 유지하지 않습니다. 약간의 연구가 끝나면 제한 절을 넣거나 중첩 쿼리를 사용하면 작동한다는 것을 알았습니다. 그래서, 아래의 두 가지 방법은 다음과 같습니다

접근-1 : 제한 조항

  select columnA1, columnA2 from tableA order by [columnA3] asc Limit 100000000 
     union distinct 
     select columnB1, columnB2 from tableB 

내가 몇 가지 데이터 세트를 사용하여이 동작을 테스트 한이 지속적으로 작동하는 것 같다. 또한 MySQL의 문서 (http://dev.mysql.com/doc/refman/5.1/en/union.html)에서이 동작에 대한 참조가 있습니다. "개별 SELECT 문에 ORDER BY를 사용하면 기본적으로 UNION이 순서가 지정되지 않은 집합을 생성하기 때문에 행이 최종 결과에 나타나는 순서는 아무런 의미가 없습니다. 행 수 따라서이 컨텍스트에서 ORDER BY를 사용하면 대개 LIMIT와 함께 사용되므로 SELECT에 대해 검색 할 선택된 행의 하위 집합을 결정하는 데 사용되므로 반드시 SELECT 문에서 행의 순서에 영향을주지는 않지만 최종 UNION 결과. SELECT에서 LIMIT없이 ORDER BY가 나타나면 아무 효과가 없으므로 최적화되어 있습니다. "

충분히 높은 숫자를 사용하는 것 외에 10000000000의 LIMIT를 선택하는 특별한 이유는 없습니다. 우리는 모든 사례를 다룹니다.

Approach-2 : 아래처럼 중첩 된 쿼리도 작동합니다.

 select column1, column2 from 
     (select column1, column2 order by [columnA3] asc) alias1 
     union distinct 
     (select column1, column2 from tableB) 

중첩 된 쿼리가 작동하는 이유를 찾을 수 없습니다. Phil McCarley (http://dev.mysql.com/doc/refman/5.0/en/union.html)와 같은 온라인 참조가 있지만 MySQL의 공식 문서는 없습니다.