2009-11-16 4 views
1

키워드를 포함한 많은 책 관련 필드가있는이 테이블을 가지고 있습니다. Book_ids는 기본 키입니다. 예를 들어 6 개의 키워드로 된 책이 있다고 가정하면 두 개 이상의 동일한 키워드가있는 다른 모든 도서를 검색하려면 어떻게해야합니까?2 개 이상의 히트 수가있는 경우의 SQL

select book_id 
from book_fields 
where keyword in (select keyword from book_fields where book_id='123') 

목적은 키워드를 기반으로 유사한 책의 대략적인 권고를 얻을 수 있습니다 :

는 내가 지금 가지고있는 것은 약이있다. 가능한 경우 SQL을 사용하여이 작업을 수행하고 싶습니다.

설명 : 아이디어는 두 개 이상의 키워드를 사용하여 책을 다른 책과 대조하는 것입니다. 모든 책의 모든 키워드는 book_fields 테이블에 있습니다. 스키마를 만질 기회가 없었으며 RDMS는 오라클이었습니다.

+1

당신은 더 명시해야합니다 방법 키워드 필드로 (적어도, 우리에게 힌트를 줄) 또는 필드가 구조화되어 있습니다. 바라건대, 그들은 레코드 당 하나의 키워드로 별도의 테이블에 있습니다. 그렇지 않은 경우 별도의 필드에 있습니까? 또는 단일 필드에서 쉼표로 구분됩니까? –

+0

테이블 정의 (열 이름, 데이터 유형 및 내용), 샘플 데이터 및 원하는 결과를 게시해야합니다. 답변을 얻기에 충분한 정보를 제공하지 않았습니다. –

+1

어떤 RDBMS를 사용하고 있습니까? – Quassnoi

답변

2

을 일대 테이블, KeywordsToBooks, 다음 스키마를 갖는

bookID로서 INT
키워드 varchar

두 개의 열이 PK로, BookID가 FKB로 사용되며 Books 테이블에 @B

SELECT BookID, COUNT(BookID) AS KeywordMatches 
FROM KeywordsToBooks 
WHERE BookID <> @BookToMatchID AND Keyword IN (
    SELECT Keyword 
    FROM KeywordsToBooks 
    WHERE BookID = @BookToMatchID) 
GROUP BY BookID 
HAVING COUNT(BookID) >= 2 

을 다른의로 제안이 도움이되지 않는 경우에, 당신은 당신의 스키마의 관련 비트를 게시 할 수 있습니다 : 당신은 매개 변수로 일치 할 책의 ID로 ookToMatchID, 여기에 내가 할 줄거야 부디?

+0

당신은 내 마음을 읽었습니다. 이것은 정확히 제가 목표로 한 것입니다. – Illotus

0

이 문제는 모든 키워드가 들어있는 표를 생성하면 더 쉽게 해결할 수 있습니다.

실현 가능합니까? 책이 테이블에 저장되어 있다고 가정

2

books 이름 : 당신이 가정

SELECT * 
FROM books bo 
WHERE (
     SELECT 1 
     FROM book_fields bf 
     JOIN book_fields br 
     ON  bf.keyword = br.keyword 
     WHERE br.book_id = 123 
       AND bf.book_id = bo.id 
     LIMIT 1, 1 
     ) = 1 
3
BEGIN; 

CREATE SCHEMA books; 
SET search_path TO books; 

CREATE TABLE book_fields (
    book_id INT NOT NULL 
, keyword VARCHAR(30) NOT NULL 
, PRIMARY KEY (book_id, keyword) 
); 

INSERT INTO book_fields (book_id, keyword) 
VALUES 
    (10, 'foo') 
, (10, 'bar') 
, (10, 'baz') 
, (20, 'foo') 
, (20, 'xxx') 
, (20, 'baz') 
, (30, 'yyy') 
, (30, 'zzz') 
; 

SELECT 
    lhs.book_id AS thisbook 
, rhs.book_id AS otherbook 
, COUNT(rhs.keyword) 
FROM book_fields lhs, book_fields rhs 
WHERE lhs.book_id <> rhs.book_id 
    AND lhs.keyword = rhs.keyword 
GROUP BY lhs.book_id, rhs.book_id 
; 

ROLLBACK; 
+0

+1은 조인의 관계 순도를 나타냅니다. 그게 나를 관계 주의자가되게합니까? – outis

+0

또한 두 개 이상의 키워드에 대한 OP의 요구 사항을 충족하려면 'HAVING COUNT (rhs.keyword)> 1'을 추가하십시오. – outis

1

더 나은 성능을 위해 ristonj이 시사하는 어떤 약 않지만, IN 절을 사용하지 마십시오 :

SELECT book_id, COUNT(*) 
    FROM book_fields b 
WHERE EXISTS (SELECT 1 
       FROM book_fields a 
       WHERE a.keyword = b.keyword 
        AND a.book_id = '123') 
GROUP BY book_id 
HAVING COUNT(*) >= 2 
+1

팁 주셔서 감사. 이 작은 쿼리가 일부 포함 된 쿼리의 순서가 달라졌습니다. – Illotus

+0

문제 없으니 도움이 되니 기쁩니다. – Tom

관련 문제