查找与其他实体相关的实体(多对多关系)

问题描述 投票:0回答:1

TL;DR problem

实体A与实体B有很多关系。给定一些实体B,如何找到与给定实体B相关的所有实体A?

实际问题

我目前有点陷入SELECTing行的问题,这些行存在多对多的关系。问题可以这样说:

实体A:Book

每本书都存储在一个名为Books的表中,如下所示:

DESCRIBE Books;
book_id  |   book_name  |  ... other metadata on books
-- book_id is a PRIMARY KEY

实体B:Genres

某种类型的流派,如冒险或浪漫,在这样的表格中举行:

DESCRIBE Genres;
genre_id  |  genre_name
-- genre_id is a PRIMARY KEY 

关系持有人:BookGenres

每个Entity A,书,可以与多个Entity B,流派有关。例如,哈利波特可以与genre_names相关:'冒险'和'幻想'。关系存储在这里。每排一个(book_id, genre_id)元组

DESCRIBE BookGenres;
book_id  |  genre_id
-- book_id REFERENCES Books(book_id)
-- genre_id REFERENCES Genres(genre_id)
-- (book_id, genre_id) is UNIQUE pairing

我想能够SELECT的书籍有一些理想的流派。让我们说,我想要返回所有book_id,其中的书有“冒险”和“幻想”类型。我能做的最好的是自我INNER JOIN并检查配对('冒险','幻想')是否存在并返回book_id,但这非常慢,如果我正在寻找n genres关系,我需要n INNER JOINS! (不可接受的)。我的查询看起来像这样:

SELECT t1.book_id
FROM BookGenres as t1
INNER JOIN Genres as t2
ON t2.genre_id = t1.genre_id
INNER JOIN BookGenres as t3
ON t3.book_id = t1.book_id
INNER JOIN Genres as t4
ON t4.genre_id = t3.genre_id
WHERE t2.genre_name = 'Adventure' AND t4.genre_name = 'Fantasy'

要搜索具有n指定关系到所需类型的书籍,我执行n self INNER JOINS并检查是否存在这样的配对。这似乎是非常低效的,我想对这个查询提供一点帮助,因为我确信这是一个常见的问题。

sql
1个回答
0
投票

对于初学者来说,你的书籍和流派之间的关系是多对多关系,而不是一对多的关系。

据我了解您的问题,您想要返回与所有选定类型相匹配的所有书籍的列表。假设您需要有关该书的其他信息,我已经包含了Books表

SELECT
    Books.book_id
FROM
    Books 
WHERE
    book_id IN (SELECT book_id 
                FROM BookGenres INNER JOIN Genres ON BookGenres.genre_id = Genres.genre_id
                WHERE Genre.genre_name = 'Adventure') AND 
    book_id IN (SELECT book_id 
                FROM BookGenres INNER JOIN Genres ON BookGenres.genre_id = Genres.genre_id
                WHERE Genre.genre_name = 'Fantasy') 
© www.soinside.com 2019 - 2024. All rights reserved.