2011-01-01 3 views
1

여기 내 테이블입니다 :SQL - 각 레코드를 반환 한 번만

tblBusiness 
BusinessID, BusinessName 

tblTags 
TagID, Tag 

tblBusinessTagLink 
BusinessID, TagID 

모든 사업에 적용된 여러 개의 태그를 사용할 수 있습니다. 이제 사용자가 'Office Supplies'및 'Technology'태그가 지정된 비즈니스 만 찾을 수 있도록 사용자가 필터링되고 있습니다.

어떤 SQL 문을 사용해야합니까? 내가 여기 제시 한 것보다 탁자에 더 좋은 디자인이 있습니까? 당신은 간단하게 사용할 수 있습니다

답변

2
SELECT 
    b.BusinessId, 
    b.BusinessName 
FROM 
    tblBusiness AS b 
    INNER JOIN tblBusinessTagLink AS l ON l.BusinessId = b.BusinessId 
    INNER JOIN tblTags   AS t ON t.TagId  = l.TagId 
WHERE 
    t.TagName IN ('Technology', 'Office Supplies') 
GROUP BY 
    b.BusinessId, 
    b.BusinessName 

이에서 둘 중 하나 범주의 모든 사업을 선택합니다. 단지 두 종류의 사람을 선택하려면, 당신은 당신이 (A m를 대표하는 세 개의 테이블을 : N의 관계) 사용되는

HAVING COUNT(*) = 2 

방법을 추가 할 수있는이 작업을 해결하는 표준 방법입니다, 당신은 유지할 수 있습니다.

개인적으로 테이블 이름에 "헝가리 표기법"을 사용하지 않으며 다른 테이블이 복수형이 아닌 경우 복수형 테이블 이름 (즉, "태그"가 아닌)을 사용하지 않을 것입니다. 아래의 첫 번째 코멘트 응답


: 큰 데이터 세트에 대한

는이 쿼리의 성능 인덱스에 의존합니다. 모든 기본 키에는 자연스럽게 색인이 필요합니다. tblBusinessTagLink에는 복합 색인에서 첫 번째로 오지 않는 필드에 대해 두 필드와 추가 색인을 모두 포함하는 복합 색인이 있어야합니다.

WHERE keywords LIKE '%technology%' 아이디어는 좋지 않습니다. 이는 필드 시작 검색 이외의 다른 조건 (예 : 데이터 집합이 커짐에 따라 성능이 급속히 저하됨)과 부분적으로 WHERE ','+keywords+',' LIKE '%,technology,%' 또는 부분 일치/가양 성을 얻을 수 있습니다.

또한 TagId으로 쿼리하는 것이 더 효율적일 수 있습니다. 당신이 가입 전체에서 하나 개의 테이블을 제거 할 수있는이 방법 :

FROM 
    tblBusiness AS b 
    INNER JOIN tblBusinessTagLink AS l ON l.BusinessId = b.BusinessId 
WHERE 
    l.TagId IN (1, 2) 

당신은 그러나 TagName에 의해 조회하려는 경우,이 필드에 인덱스뿐만 아니라 절대적으로 필요합니다.

+0

헝가리 표기법과 복수형에 대한 메모에 감사드립니다. 나는 여전히 Access 데이터베이스를 구축하는 동안 배운 모든 것을 취소하려고 노력 중이다. 비즈니스 항목의 수량이 증가하면이 쿼리의 성능이 저하됩니까? 또는 선택한 태그의 수가 증가하면? 아니면 둘다? 필자는 사용자에게 5 ~ 6 개의 태그가 적용된 레코드를 선택할 수있는 옵션을 제공 할 계획입니다. 때로는 태그를 가져 와서 키워드 필드에 저장하는 것이 더 빠르지 않을지 궁금해합니다. 따라서 '% technology %'와 (과) 같은 키워드를 tblBusiness에서 b.BusinessID, b.BusinessName을 선택할 수 있습니다. – HK1

+0

추가 의견보기 내 대답은. – Tomalak

0

는 기록을

SELECT t.Tag, b.BusinessName 
FROM tblBusiness b, tblTags t, tblBusinessTagLink l 
WHERE t.TagID = l.TagID 
AND l.BusinessID = b.BusinessID 
AND t.Tag = 'Office Supplies' 
('사무용품'하나와 '기술'의 하나)
+0

몇 가지를 이해하지 못합니다. "t"와 "b"는 테이블 이름입니까?조인 문은 어디에 있습니까? 또는이 SQL 문에 조인이 필요하지 않습니까? 또한 '기술'태그를 지정하지 않았습니다. – HK1

+0

이들은 별칭 테이블 이름입니다 – DKnight

+0

두 개의 범주를 선택하고 내 쿼리에서 결과를 얻지 못하면 올바른 레코드를 반환하려고 시도했습니다. t.Tag, b.BusinessName tblBusiness에서, tblTags에서 tbl, tblBusinessTagLink로 l WHERE (t.Tag = '사무 용품'과 t.TagID = [l]. [TagID] AND l.BusinessID = b]. [BusinessID]) AND (t.Tag = '기술'및 t.TagID = [l]. [TagID] AND l.BusinessID = [b]. [BusinessID]); – HK1

-1

당신은이 쿼리를 병합 할 INTERSECT 설정 작업을 사용할 수 있습니다를 얻기 위해 가입.

그러나 INTERSECT를 지원하지 않는 MySQL을 사용하는 경우 'HAVING COUNT (*) = 2'like this 인 UNION ALL을 사용할 수 있습니다.


는 편집 :

또한 ALL과 같이 연합하지 않고 두 번째 옵션을 사용할 수는 :

select Name from tblBusiness 
left join tblBusinessTagLink on tblBusinessTagLink.BusinessID = tblBusiness.ID 
left join tblTags on tblTags.TagID = tblBusinessTagLink.TagID 
where Tag = 'Office Supplies' or Tag = 'Technology' 
group by name 
having count(Name) = 2; 
+0

당신의 솔루션이 Tomalak 's와 같은지 알아 내려고하고 있습니다. 사용자가 "OR"대신 "AND"를 사용하여 한 번에 3 개 또는 4 개의 태그를 적용하려면 어떻게해야합니까? – HK1

+0

Tomalak과 내 솔루션이 모두 같다고 믿습니다. (그러나 'x가 (y, z) 인 곳'과 'x = y 또는 x = z'가있는 곳) 벤치마킹을하는 것이 좋습니다. 또한 하나의 비즈니스가 동일한 태그를 두 번 가지지 않는다면 올바르게 작동하지 않을 것입니다. 의견을 보내 주셔서 감사합니다. – threenplusone

+0

사용자가 동일한 태그를 두 번 입력하지 못하도록 조치를 취할 것입니다. – HK1

관련 문제