2011-05-07 3 views
1

전자 메일과 도메인이있는 두 개의 테이블이 있습니다.다른 테이블의 문자열과 부분적으로 일치하는 MySQL SELECT 행

Table1     Table2 
id email    id domain 
-- ----     -- ---- 
1 [email protected]  1 domain1.com 
2 [email protected]  2 domain4.com 
3 [email protected] 
4 [email protected] 

는 지금은 결과가 있어야 도메인이 표 2의 도메인 필드와 일치 표 1에서 모든 메일을 선택합니다 :

id email 
-- ---- 
1 [email protected] 
4 [email protected] 

나는 그것이 정규 표현식의 조합 일 것 같아요 INNER JOIN? 그러나 나는 그것들을 결합하는 방법을 모른다.

답변

3

해결 방법 1 :

사용 Table1.email LIKE CONCAT('%@',Table2.domain).

BIG FAT RED 경고 :이 조건은 인덱싱되지 않습니다. 속도를 원하면 전자 메일을 Table1의 주소와 도메인으로 분할하고 색인을 만듭니다.

편집 : 아마 가장 느린 방법 그래서

사실이 가입 조건은, 수 (이메일) xcount (도메인) 비교가 필요합니다.

해결 방법 2 :

롭 아주 좋은 포인트가 : 빠른 방법은 (문자열을 사용하여) 전자 메일에서 도메인을 추출하고 도메인 테이블에 인덱스에 대해이 일치하는 것입니다

해결 방법 3 :

가장 좋은 방법은 이메일의 도메인을 색인하는 것입니다. Postgres에서 함수 extract_domain (email)을 생성하면 (간단히 extract_domain() 함수를 생성한다고 가정), MySQL에서는이 작업을 수행 할 수 없기 때문에 도메인을 가진 추가 컬럼이 속도 향상을위한 방법입니다.

하나 개 도메인의 모든 이메일을 알고 싶은 경우

,

Solution 1 : seq scan table emails + fast LIKE 
Solution 2 : seq scan table emails + slightly slower domain extraction 
Solution 3 : index scan table emails 

모든 도메인에 대한 테이블 도메인/모든 이메일에 가입 할 경우 전체를 들어

Solution 1 : count(email)xcount(domain) comparisons, very slow 
Solution 2 : seq scan table emails + index scan domains 
Solution 3 : nested loop index join 

을 것이다 가입 병합 조인이나 해시 조인을 사용하는 것이 더 빠르지 만, mysql에서는 제공되지 않습니다.

+0

방법 SUBSTRING_INDEX에 대한 (Table1.email, '@', -1) = Table2.domain Table2.domain에 대한 인덱스가 있습니까? – Rob

+0

Table2.Domain의 색인은 도메인 목록이 전자 메일 목록보다 훨씬 작기 때문에 별다른 이점이 없습니다. –

+0

@Rob : 비교되는 데이터가 인덱스의 내용과 다르기 때문에 테이블 열의 모든 연산은 인덱스를 쓸모 없게 만듭니다. –

2

SELECT t1.Id, 
     t1.Email 
    FROM Table1 t1 
    JOIN Table2 t2 ON t1.email LIKE CONCAT('%@', t2.Domain); 
+0

AFAIK 당신은'MySQL'에서'CONCAT'을 사용해야합니다. –

+0

@Martin : 아니오, MySQL은 문자열을 연결하기 위해'CONCAT'을 요구하지 않습니다.또한 Oracle도 마찬가지입니다. –

+0

아, 나는'+'를 사용하여 숫자로 변환 할 때 '0'을 반환한다는 것을 기억했다. 아마 다른 다른 RDBMS 일 수도 있습니다. –

4

을이 밖으로 시도 내가 표를 생성하고 테스트를했고,이 쿼리는 나를 위해 일한 :

SELECT t1.*, t2.domain FROM t1 
INNER JOIN t2 ON t1.email LIKE CONCAT('%@', t2.domain); 
+0

당신이 옳았습니다. 내 실수였습니다. 나는 내 대답을 편집했다. – PachinSV

+0

+1 : ANSI-92 JOIN 구문을 사용해 주셔서 감사합니다. :) –

관련 문제