2012-04-17 2 views
2

배경 : 나는 자신의 이미지 컬렉션을 관리하기위한 자작 프로젝트를 진행하고 있으며 태그 기반 검색을 구현하려고 노력하고있어이를 통해 쉽게 눈을 뗄 수 있습니다."태그"검색/제외 쿼리 디자인 문제

지금 당장은 각 이미지의 데이터베이스 항목에 태그를 적용하기 위해 RedBean의 태그 지정 API를 사용하고 있지만 구현에 대한 구체적인 세부 사항을 알고 있습니다. 현재, (태그 이미지 "XYZ"를 "ABC"를 태그가 있어야합니다 "ABC XYZ"를 검색 할 때) 여러 태그 검색을 구체화한다 태그의 검색,

나는 몇 가지를 처리하는 데 허용하는 SQL이 아닌 서버 측 언어로 처리 한 다음 (선택적) 두 번째 쿼리를 실행하여 반환 된 이미지에 결과에서 명시 적으로 제외 된 태그가 없는지 확인합니다. ("ABC -XYZ"를 검색 할 때 태그가 지정된 이미지는 태그 "ABC"이고 이 아니고 "XYZ"가 아님)이 있어야합니다.

여기의 문제는 현재 사용중인 방법이 서버 측 코드로 모든 결과를 실행하고 합리적인 페이지 매김/결과 오프셋의 모든 시도를 부정확하게 수행해야한다는 것입니다.

내 목표는 하나의 쿼리로 요청한 태그를 포함하고 제외 된 태그를 포함하지 않는 행을 가져 와서 합리적으로 페이지 매김을 얻기 위해 내 쿼리에 대해 LIMIT/OFFSET 인수를 사용할 수있게하는 것입니다. 결과. 다음과 같이

테이블 스키마는 다음과 같습니다

Table "post" 
Columns: 
    id (PRIMARY KEY for post table) 
    (image metadata, not relevant to tag search) 

Table "tag" 
Columns: 
    id (PRIMARY KEY for tag table) 
    title (string of varying length - assume varchar(255)) 

Table "post_tag" 
Columns: 
    id (PRIMARY KEY for post_tag table) 
    post_id (associated with column "post.id") 
    tag_id (associated with column "tag.id") 

가능하다면, 나는 또한 WHERE post 테이블 컬럼에 특정 조건뿐만 아니라 가질 수 있도록하고 싶습니다.

쿼리 구조에는 무엇을 사용해야합니까? 나는 왼쪽 조인으로 놀았지만 이것을 해결하기 위해 필요한 정확한 구조를 얻을 수 없었습니다.

LEFT OUTER JOIN은 제외 할 태그를 일치 게시물의 설정은 다음과 같습니다

답변

2

여기에 기본적인 생각이다. 쿼리의 마지막 WHERE 절은 이러한 게시물 중 첫 번째 post 테이블의 항목과 일치하지 않습니다.

INNER JOIN은 모든 태그와 일치하는 게시물 집합입니다. 두 번째 숫자는 IN 절에서 제공하는 고유 한 태그 이름 수와 일치해야합니다.

select p.* 
from post p 
left outer join (
    select pt.post_id  
    from post_tag pt 
    inner join tag t on pt.tag_id = t.id 
    where t.title in ('UVW', 'XYZ') 
) notag on p.id = notag.post_id 
inner join (
    select pt.post_id  
    from post_tag pt 
    inner join tag t on pt.tag_id = t.id 
    where t.title in ('ABC', 'DEF') 
    group by pt.post_id 
    having count(distinct t.title) = 2 
) yestag on p.id = yestag.post_id 
where notag.post_id is null 
--add additional WHERE filters here as needed 
+0

SQLite에서 작동하지 않는 것으로 나타나며 행이 반환되지 않습니다. 테스트 베드 DB를 MySQL로 신속하게 마이그레이션하고 어떻게 진행되는지 살펴 보겠습니다. – damianb

+0

MySQL에는 주사위가 없습니다. 테스트 베드 db에 두 개의 게시물이 있는데, 하나는'("abc", "def", "ghi")'이고 다른 하나는'("abc", "def", "xyz") 태그입니다. '("xyz")'의 exclude/left-outer-join과 결과가없는'("abc", "def")의 검색/내부 조인을 사용하여 쿼리를 시도했습니다. 나는 구조와 함께 주위에 땜질하고, 내가 화를 내고있는 곳을 발견 할 수 있는지 알 것이다. – damianb

+0

그냥 "설명"쿼리를 실행, 나는 첫 번째 청크에 대한이 얻을 : "불가능한 어디 const 테이블을 읽은 후 발견". – damianb