현재 태그 클라우드 시스템을 작성 중입니다. 다 대다 SQL 선택
그래서 나는 다음과 같은 SQL 스키마 썼다 :CREATE TABLE bookmark_model_bookmark (
id INTEGER NOT NULL,
link VARCHAR(255),
title VARCHAR(140),
description TEXT,
PRIMARY KEY (id)
);
CREATE TABLE bookmark_model_tag (
id INTEGER NOT NULL,
name VARCHAR(20),
PRIMARY KEY (id)
);
CREATE TABLE bookmark_tag (
bookmark_model_bookmark_id INTEGER NOT NULL,
bookmark_model_tag_id INTEGER NOT NULL,
PRIMARY KEY (bookmark_model_bookmark_id, bookmark_model_tag_id),
CONSTRAINT bookmark_model_bookmark_tags_fk FOREIGN KEY(bookmark_model_bookmark_id) REFERENCES bookmark_model_bookmark (id),
CONSTRAINT bookmark_model_tag_bookmarks_fk FOREIGN KEY(bookmark_model_tag_id) REFERENCES bookmark_model_tag (id)
);
을 그리고 적은 양의 데이터로 채우기 : 가독성 측면에서
SELECT * FROM bookmark_model_bookmark;
1|http://braindead.fr|braindead|
2|http://example.fr|example|example text
SELECT * FROM bookmark_model_tag;
1|test
2|braindead
3|example
SELECT * FROM bookmark_tag;
1|1
1|2
2|1
2|3
:
- 즐겨 찾기 # 1 braindead는 http://braindead.fr/을 참조하고 두 개의 태그가 있습니다 : "test"와 "braindead".
- 북마크 # 2라는 이름의 예제는 http://example.fr/을 참조하며 "test"및 "example"에 태그를 지정해야합니다.
그래서 내 개발의 다음 단계는 선택한 태그 목록으로 태그가 지정된 책갈피에 링크 된 모든 태그를 선택하는 것입니다.
예를 들어 매개 변수 "test"에서 "braindead"와 "example"을 반환해야합니다. 둘 다 테스트 태그로 태그가 지정되어 있기 때문입니다.
"test"및 "braindead"매개 변수를 전달하는 경우 "test"및 "braindead"태그가있는 유일한 책갈피이므로 "braindead"만 쿼리에서 반환해야합니다.
SELECT *
FROM bookmark_model_tag AS tag
INNER JOIN bookmark_tag ON (bookmark_tag.bookmark_model_tag_id = tag.id)
WHERE bookmark_tag.bookmark_model_bookmark_id IN (/* Here my subquery */);
하지만 하위 쿼리를 찾을 수 없습니다. 나는 이런 식으로 시작해야한다 :
SELECT bookmark.id
FROM bookmark_model_bookmark AS bookmark
INNER JOIN bookmark_tag ON (bookmark.id = bookmark_tag.bookmark_model_bookmark_id)
WHERE /* what to write here ? */
정확히 말하면, 내 쿼리의 입력 매개 변수는 태그 ID의 배열이다.
그래서 여기에 붙어 있습니다.
편집
내가하는 ORM (SQLAlchemy의)를 사용하여 내 쿼리를 작성, 그것은 다음과 같습니다 쿼리를 작성입니다 해요 :
이 여전히 문제가되는 경우SELECT tag.id AS tag_id, tag.name AS tag_name, count(tag.id) AS count_1
FROM tag, bookmark_tag, (
SELECT bookmark.id AS id
FROM bookmark, bookmark_tag
WHERE bookmark.id = bookmark_tag.bookmark_id
AND bookmark_tag.tag_id IN (1, 2)
GROUP BY bookmark.id
HAVING count(bookmark.id) = 2) AS anon_1
WHERE tag.id = bookmark_tag.tag_id
AND bookmark_tag.bookmark_id = anon_1.id
AND tag.id NOT IN (1, 2)
GROUP BY tag.id
이것은 [Relational Division] (http://www.simple-talk.com/sql/t-sql-programming/divided-we-stand-the-sql-of-relational-division/)입니다. 가장 일반적인 접근 방식은 'GROUP BY'와 'COUNT'인 것 같습니다. –
내 where 절이 이제 "WHERE bookmark_tag.bookmark_model_tag_id IN ($ TAG_LIST_ID) GROUP BY bookmark.id HAVING count (*) == $ TAG_LIST_SIZE"가되었습니다. 그게 당신이 기대하는 것입니까? –
예. 'bookmark_tag'에 고유 한 제약 조건이 있다고 가정하면 동일한 콤보에 대해 중복을 가질 수 없습니다. –