2013-03-25 3 views
2

먼저, 질문을 읽은 후에 누군가가이 질문에 대한보다 유익한 제목에 대한 제안을하면,mysql - 다른 열 값을 기준으로 상호 배타적으로 선택하십시오.

+---------+-------------------------------------+------+-----+---------+----------------+ 
| Field | Type        | Null | Key | Default | Extra   | 
+---------+-------------------------------------+------+-----+---------+----------------+ 
| id  | int(11)        | NO | PRI | NULL | auto_increment | 
| account | varchar(20)       | YES | UNI | NULL |    | 
| domain | varchar(100)      | YES |  | NULL |    | 
| status | enum('FAILED','PENDING','COMPLETE') | YES |  | NULL |    | 
+---------+-------------------------------------+------+-----+---------+----------------+ 

그리고이 데이터 :

+----+---------+------------------+----------+ 
| id | account | domain   | status | 
+----+---------+------------------+----------+ 
| 1 | jim  | somedomain.com | COMPLETE | 
| 2 | bob  | somedomain.com | COMPLETE | 
| 3 | joe  | somedomain.com | COMPLETE | 
| 4 | frank | otherdomain.com | COMPLETE | 
| 5 | betty | otherdomain.com | PENDING | 
| 6 | shirley | otherdomain.com | FAILED | 
| 7 | tom  | thirddomain.com | FAILED | 
| 8 | lou  | fourthdomain.com | COMPLETE | 
+----+---------+------------------+----------+ 

내가 셀렉 싶습니다 난 내 다소

이 테이블 구조를 감안할 때 ... 사업에, 지금 부족한 생각 모든 계정 (행)에 대해 'COMPLETE'상태를 갖는 모든 도메인.

상태에 대해 'COMPLETE'이외의 값이 포함 된 행이있는 도메인은 반환되지 않아야합니다.

그래서 위의 예에서 내 예상 된 결과는 다음과 같습니다 분명히

+------------------+ 
| domain   | 
+------------------+ 
| somedomain.com | 
| fourthdomain.com | 
+------------------+ 

, 내가 이것을 달성 할 수와 같은 하위 쿼리를 사용하여 :

mysql> select distinct domain from test_table where status = 'complete' and domain not in (select distinct domain from test_table where status != 'complete'); 
+------------------+ 
| domain   | 
+------------------+ 
| somedomain.com | 
| fourthdomain.com | 
+------------------+ 
2 rows in set (0.00 sec) 

이 잘에 작동합니다 우리의 작은 실물 크기의 테스트 테이블,하지만 실제 상황에서, 문제의 테이블은 수십 (또는 심지어 수백) 행이 될 것입니다 그리고 어떤 경우 더 효율적인지 방법이 궁금 해서요 하위 쿼리는 느리고 집중적입니다. 이 방법에 대해

답변

2

는 :

select domain 
from test_table 
group by domain 
having sum(case when status = 'COMPLETE' 
       then 0 else 1 end) = 0 
+0

우수! 이것은 내가 필요한 것입니다. –

+0

답변에 대한 내 의견을 참조하십시오. –

+0

+1 분명히 v.를 잘 수행하고 부팅하기가 쉽다. 좋은 것. – Sepster

0

나는이 일 것이라 생각합니다. 효과적으로 두 개의 기본 쿼리를 결합한 다음 그 수를 비교합니다.

select 
    main.domain 
from 
    your_table main 

    inner join 
    (
     select 
      domain, count(id) as cnt 
     from 
      your_table 
     where 
      status = 'complete' 
     group by 
      domain 
    ) complete 
    on complete.domain = main.domain 

group by 
    main.domain 

having 
    count(main.id) = complete.cnt 

또한 이것은 그 열에 참여에 의존 당신이 domain에 인덱스를 확인해야합니다.

+0

이 방법은 하위 쿼리보다 성능이 좋지만 다른 답변을 선택한 이유는이 쿼리가 상당히 우수한 성능을 발휘하기 때문입니다. 10K 행이있는 테이블에서 쿼리는 5.56 초에 작업을 수행하고 다른 응답은 0.11을 사용했습니다. –

+0

@jesse_galley 실수에 대해 죄송합니다. 손이 텍스트 편집기로 작성되었습니다. 공정한 충분한 성능, mySql이 최종 결과의 각 행에 대한 케이스를 매우 신속하게 구현해야하는 것처럼 보입니다 ... 아니면 영리한 최적화를 수행하십시오. 지금은 실제로 단순화했습니다. 다시 확인하는 데 관심이 있다면 몰라요. 그것이 더 빨리 될 것이 확실하지 않지만, 빠른 점검의 가치가 있을지도 모른다. 그러나 단호하게 다른 대답과 일치 할 수는 없습니다. 행운을 빈다. +1, 질문. 잘 물었다. – Sepster

관련 문제