根据另一个表中的选定行从一个表中选择数据

时间:2019-03-09 14:52:21

标签: sql database postgresql

我有三个表:

书籍:

{id, title, status}
{1, SuperHero, false}
{2, Hobbit, true}
{3, Marvel, true}

标签:

{id, name}
{1, Drama}
{2, Comedy}
{3, Triller}

books_tags:

{book_id, tag_id}
{1, 1}
{1, 2}
{2, 2}

每本书的标签都有或没有很多。

1)在基于book_id的一次查询中,获取一本书的所有带有数据(tag.id,名称)的标签的正确方法是什么?

2)在一个查询中,为每本书行按状态(true)获取带有标签数组的所有书籍的正确方法是什么?

我为第一个提出了这个建议,但在第二个方面却苦苦挣扎:

SELECT tag_id, name 
FROM books_tags 
    INNER JOIN tags ON tag_id = tags.id 
WHERE book_id = 1

2 个答案:

答案 0 :(得分:1)

对于第二个要求,请使用以下内容:

SELECT
    b.title,
    array_agg(t.name) AS tags
FROM books AS b
INNER JOIN books_tags AS bt ON (b.id = bt.book_id)
INNER JOIN tags AS t ON (bt.tag_id = t.id)
WHERE b.status = true
GROUP BY 1;

答案 1 :(得分:1)

在Postgres中,您可以使用array type,在这种情况下,这可以使您的生活变得更加轻松,并且使books_tags表过时。

请考虑以下设置:

keep_radicand_safe

现在,您可以轻松执行查询。例如1)

False

如果要将标签放在单独的行中,请使用create temp table if not exists tags( id int, name text ); insert into tags(id, name) values (1, 'Drama') ,(2, 'Comedy') ,(3, 'Thriller'); create temp table if not exists books( id int, title text, status bool, book_tags int[] ); insert into books(id, title, status, book_tags) values (1, 'SuperHero', false, array[1, 2]) ,(2, 'Hobbit', true, array[2]) ,(3, 'Marvel', true, null); 函数,例如

select  book_tags
from    books B 
where   B.id = 1;

和2)查找所有带有unnest()select unnest(book_tags) from books B where B.id = 1;

的图书
tag in [2]

您的样本数据的第一本书有status = true,因此select id, title, book_tags from books B where B.status = true and B.book_tags @> array[2] -- set query tags in on right side 不会带回该数据的任何结果。因此,我将示例设置为仅使用一个标签。