2011-01-12 3 views
0

저는 각 그룹에 저장된 연락처 목록을 가져 오는 작은 프로젝트를 진행하고 있습니다. 본질적으로 데이터베이스는 각 그룹이 Group.Primary 및 Group.Secondary로 저장되는 기본 및 보조 연락처를 가지도록 설정됩니다. 목표는 각 그룹의 모든 1 차 및 2 차 담당자를 선별하여 정렬 가능한 테이블에 표시하는 것입니다.MySQL의 질의 열과 같은 열

나는 정렬 가능한 테이블을 모두 가지고 있지만, 나는 작은 문제를 보았다. 각 기본 및 보조 필드는 쉼표로 구분 된 둘 이상의 연락처를 가질 수 있습니다. 기본이 123,256 포함 된 경우 예를 들어, 내가 같은 형식의 쿼리를 사용하는 의도는 ID를 123에서 256으로 모두 연락처를 당길 필요가 : 난 그냥 쉼표 부분을 건너 뛸 수 있도록

SELECT * 
    FROM Group G, 
     Contacts C 
WHERE G.Primary LIKE %C.ID% 
    OR G.Secondary LIKE %C.ID% 

을하지만, 나는 이것에 대한 작동 쿼리를 찾을 수없는 것 같습니다.

내 질문에 내가 여기에 뭔가를 간과하고 있습니까? 이 작업을 수행 할 수있는 간단한 쿼리가 있습니까? 아니면 그룹과 연락처를 따로 얻는 것이 낫지 만 나중에 두 가지를 결합하는 것이 좋습니다. 저는 이전에 읽었을 때 좀 더 이해하기 쉽다고 생각합니다. 이것은 공유 프로젝트이기 때문에 더하기는하지만 가능하지 않다면 후자를 할 것입니다.

이 코드는 단순화되었지만 요점을 가져옵니다. 만약 내가 제대로 이해하고

+0

데이터베이스 내에 일대 다 관계가 있습니다. 하나의 그룹에는 하나 이상의 연락처가 연관되어 있습니다. 대부분의 사람들은 groupid 및 연락처 ID 조합이 포함 된 추가 테이블을 추가하여이 문제를 해결합니다. 이 방법을 사용하면 일반 조인을 사용하여 그룹과 관련된 모든 연락처를 얻을 수 있습니다. 추가 된 장점은 매번 쉼표로 구분 된 값으로 문자열을 '구문 분석'하는 것보다 훨씬 빠릅니다. – Gerben

+0

슬프게도, 그것은 레거시 데이터베이스이며 너무 많은 시스템이 구조를 변경하기 위해 의존하기 때문에 그대로 유지해야합니다. 나는 해결책을 여기에서 시도 할 것이다, 내가 무엇을 만들 수 있는지 보자. – shmeeps

답변

3

, 당신은 MySQL FIND_IN_SET function 사용하려면 :

SELECT * 
    FROM Group G 
    JOIN Contacts C ON FIND_IN_SET(c.id, g.primary) 
        OR FIND_IN_SET(c.id, g.secondary) 

을하지만, 내가보기 엔 당신이 테이블을 정상화하는 것이 좋습니다 - 쉼표 저장 가능하면 모든 목록을 구분하지 않습니다.

+0

이것은 트릭을 했어, 정말 고마워! – shmeeps

0

나는이 두 데이터 값을 다른 테이블로 분리 한 다음 JOIN을 사용하여 연결하는 것이 좋습니다. id 필드를 문자열로 변환하여 LIKE 비교를 사용할 수 있다면, 많은 정크가 될 것입니다. 기본 ID는 1, 및 보조 다음 다음에 일치하는 것, 35 예를 들어, (이 목록 철저하지 않다) :

1: 1, 2: 35 
1: 35, 2: 1 
1: 10, 2: 135 
1: 431, 2: 3541 

등 내가 좋겠

SELECT * 
FROM Group G 
LEFT JOIN Contacts c1 on g.primary = c1.id 
LEFT JOIN Contacts c2 on g.secondary = c2.id 
WHERE 
c1.id IS NOT NULL 
OR 
c2.id IS NOT NULL 

는 내가 제대로 질문을 이해하는 경우 즉, 당신이 정말 찾고있는 데이터를 얻을 수있을 거라 생각 : 대신 같은 것입니다 않습니다.

0

Satan이 데이터베이스에 비정규 화되어 복잡하고 느린 쿼리로 인해 생겨났습니다.

데이터베이스의 구조를 변경할 수 있습니까? 생산 중이라면 그렇지 않다고 생각합니다. 이 보고서를 실행하기 직전에 기본 및 보조 연락처의 정규화 된 테이블을 만드는 것이 좋습니다.

이렇게 할 수 없다면 항상 작동하는 문자열 매칭 알고리즘을 찾아야합니다. 당신이 제안한 문제는 23 (또는 심지어 3)의 연락처 ID를 고려해야한다는 것입니다.이 ID는 23, 123, 223, 231 등과 일치합니다. 이 작업을하려면 비교할 양쪽 문자열의 시작과 끝에 쉼표를 추가 한 다음 LIKE를 수행해야합니다.

또는 위의 포니 (Pony)가 설명한 I-never-knew FIND_IN_SET 함수를 사용할 수 있습니다.

+0

여기에 성가대에게 설교를하고 있지만 FIND_IN_SET조차도 여전히 정크 데이터 인 의도 한 성냥의 반전과 일치합니다. 나는 정상화가 여기에 갈 길이라는 것에 완전히 동의한다. –