SQL 查询只返回一个条目,而它应该返回多个条目

SQL query is only returning one entry, when it should be returning several

我正在创建一个图书标签系统,我试图用相同的标签调用所有图书。我的查询只查询到第一本书,而不是以下任何具有相同标签的书。

这里是数据库table的书籍

    drop table if exists books;

      create table books (
      isbn_13 varchar (13) primary key,
      title varchar (100),
      author varchar (80),
      publish_date date,
      price decimal (6,2),
      content bytea
    );

这是数据库的 book_tags table:

    CREATE TABLE book_tags
    (
        isbn_13 character varying(13) NOT NULL,
        tag_names character varying(100) NOT NULL,
        CONSTRAINT book_tags_pkey PRIMARY KEY (isbn_13, tag_names),
        CONSTRAINT book_tags_isbn_13_fkey FOREIGN KEY (isbn_13)
            REFERENCES public.books (isbn_13) MATCH SIMPLE
            ON UPDATE NO ACTION
            ON DELETE NO ACTION
    )

这是调用查询的 BookTagDAOImpl 文件:

public List<Book> getBooksByTag(String tag) {
    List<Book> books = new ArrayList<>();
    
    try {
        connection = DAOUtilities.getConnection();
        String sql = "SELECT * FROM books INNER JOIN BOOK_TAGS ON tag_names=?";
        stmt = connection.prepareStatement(sql);
        
        stmt.setString(1, tag);
        
        ResultSet rs = stmt.executeQuery();
        
        if (rs.next()) {
            Book book = new Book();
            
            book.setIsbn13(rs.getString("isbn_13"));
            book.setAuthor(rs.getString("author"));
            book.setTitle(rs.getString("title"));
            book.setPublishDate(rs.getDate("publish_date").toLocalDate());
            book.setPrice(rs.getDouble("price"));
            book.setContent(rs.getBytes("content"));    
            
            books.add(book);
        }
        System.out.println("seeing if it will pull multiple books from one tag" + books);
        
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        closeResources();
    }
    
    return books;
}

作为初学者:if 语句可能应该是一个 while 循环。

但是,这也是您查询的问题:

SELECT * FROM books INNER JOIN BOOK_TAGS ON tag_names=?

这缺少两个表之间的连接条件,所以这基本上 returns 所有书籍,只要其中至少有一个具有搜索标签。据推测,你想要:

SELECT * 
FROM books b
INNER JOIN BOOK_TAGS bt ON bt.isbn_13 = b.isbn_13
WHERE bt.tag_names = ?

你不妨使用EXISTS:

SELECT b.*
FROM books b
WHERE EXISTS (
    SELECT 1
    FROM book_tags bt
    WHERE bt.isbn_13 = b.isbn_13 AND bt.tag_names = ?
)
String sql = "SELECT * FROM books INNER JOIN BOOK_TAGS ON tag_names=?";

这不是连接语法的工作原理。我想你的意思是

SELECT * FROM books b INNER JOIN BOOK_TAGS t 
    ON b.isbn_13 = t.isbn_13 where t.tag_names=?";

由于它是内部联接,因此您不会得到任何没有匹配标签行的图书。

您还有另一个问题,因为很难找到单个标签或标签的子集,因为您需要这样做 where tag_names like '%value%'。每个标签记录应该有一个标签。