微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Postgres-多次连接导致我的查询返回错误的数据

如何解决Postgres-多次连接导致我的查询返回错误的数据

|| 我的数据库中有三个表。他们的模式基本上是:
books:
id | book_title

books_tags:
id | book_id | tag_id

books_Votes:
id | book_id | Vote
这个想法是能够搜索书籍并通过给定的标签在这种情况下为716和101)进行过滤。
total_Votes
用于ORDER BY运算符。
SELECT
    books.id AS books_id,sum(book_Votes.Vote) AS total_Votes 
FROM
    books
JOIN
    -- works fine without this join
    book_Votes ON books.id = book_Votes.book_id
JOIN
    books_tags ON books.id = books_tags.book_id
WHERE
    books_tags.tag_id IN (716,101)
GROUP BY
    books.id 
HAVING
    count(books.id) = 2
标签过滤本身就很好用。我可以根据需要向IN子句中添加任意数量标签ID,它将继续过滤结果以仅显示带有这些标签的图书。完善。 当我将第二个JOIN添加
books_Votes
表中时,会出现问题。此联接不会产生任何错误,只会导致查询返回错误的数据-就像忽略标签ID一样。 第二次加入怎么了? 编辑: 这是表中的转储:
books:
 id |   book_title  
----+-----------------
  1 | first
  2 | second
  3 | third book
  4 | fourth book
  5 | fifth
  6 | sixth book

books_tags:
 id | book_id | tag_id 
----+---------+--------
  1 |       1 |    293
  2 |       1 |     32
  3 |       1 |    370
  4 |       2 |    101
  5 |       2 |    357
  6 |       3 |    554
  7 |       3 |    808
  8 |       3 |    716
  9 |       3 |    101
 10 |       4 |    787
 11 |       4 |    808
 12 |       4 |    322
 13 |       5 |    787
 17 |       6 |    716
 18 |       6 |    554
 19 |       6 |    101

books_Votes:
 id | book_id | Vote 
----+---------+------
  2 |       2 |    1
  3 |       3 |    1
  4 |       4 |    1
  7 |       4 |    1
  8 |       2 |    1
 11 |       5 |    1
 12 |       5 |    1
 13 |       1 |    1
这是我在发布第二个联接(到books_Votes)时从我发布的查询中返回的数据:
 book_id 
---------
   6
   3
如您所见,返回了正确的书。书籍6和3已标有716和101。 这是我将books_Votes表连接到运行查询时返回的结果:
 book_id | total_Votes 
---------+-------------
    3    |    2
    2    |    3
    

解决方法

        逐步构建复杂的SQL。 这为您提供了具有两个必需标签的书籍。它仅与表定义一样可靠。您的表格定义不应允许一本书具有相同的标签两次。您需要对(book_id,tag_id)具有唯一约束。
SELECT book_id 
FROM books_tags
WHERE books_tags.tag_id IN (716,101)
GROUP BY book_id
HAVING COUNT(tag_id) = 2

book_id
--
6
3
您可以在JOIN中使用它。
SELECT books.id
FROM books
INNER JOIN (
    SELECT book_id 
    FROM books_tags
    WHERE books_tags.tag_id IN (716,101)
    GROUP BY book_id
    HAVING COUNT(tag_id) = 2) bt ON bt.book_id = books.id

book_id
--
6
3
加入投票表应从结果中删除book_id 6。 (6票无票。)
SELECT books.id
FROM books
INNER JOIN (
    SELECT book_id 
    FROM books_tags
    WHERE books_tags.tag_id IN (716,101)
    GROUP BY book_id
    HAVING COUNT(tag_id) = 2) bt ON bt.book_id = books.id
INNER JOIN books_votes bv ON bv.book_id = books.id

book_id
--
3
现在,您可以将投票栏添加到查询中。
SELECT books.id,bv.vote
FROM books
INNER JOIN (
    SELECT book_id 
        FROM books_tags
    WHERE books_tags.tag_id IN (716,101)
    GROUP BY book_id
    HAVING COUNT(tag_id) = 2) bt ON bt.book_id = books.id
INNER JOIN books_votes bv ON bv.book_id = books.id

book_id  vote
--
3        1
最后,您可以对票求和。
SELECT books.id,SUM(bv.vote) AS total_votes
FROM books
INNER JOIN (
    SELECT book_id 
        FROM books_tags
    WHERE books_tags.tag_id IN (716,101)
    GROUP BY book_id
    HAVING COUNT(tag_id) = 2) bt ON bt.book_id = books.id
INNER JOIN books_votes bv ON bv.book_id = books.id
GROUP BY books.id;

book_id  total_votes
--
3        1
您的版本无效,因为它返回了错误的图书ID号。在books_votes上的JOIN和WHERE子句的组合无法达到您的预期。
SELECT books.id AS books_id
FROM books
JOIN books_votes ON books.id = books_votes.book_id
JOIN books_tags ON books.id = books_tags.book_id
WHERE books_tags.tag_id IN (716,101)
GROUP BY books.id 

books_id
--
3
2
包括本书2并不是因为它同时具有两个标签,而是因为它具有两个投票。
SELECT books.id AS books_id,books_tags.tag_id,books_votes.vote
FROM books
JOIN books_votes ON books.id = books_votes.book_id
JOIN books_tags ON books.id = books_tags.book_id
WHERE books_tags.tag_id IN (716,101)
ORDER BY books_id,tag_id

book_id  tag_id     vote
--
2        101        1
2        101        1
3        101        1
3        716        1
    ,        据我了解,您需要所有带有标签716和101的书籍,并且需要每本书的投票数。
select *,(select count(*) from book_votes as vts where vts.book_id = bks.id) as vote_count
from books as bks
where 
    id in 
    (
        select book_id
        from books_tags as tgs
        where tgs.tag_id in (716,101)
        group by book_id
        having count(*) = 2
    )
结果:
id          book_title      vote_count
----------- --------------- -----------
3           third book      1
6           sixth book      0
    

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。