首页 > 解决方案 > SQL查询只返回一个条目,而它应该返回几个

问题描述

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

这是数据库的书籍表

    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 表:

    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;
}

标签: javasqljspinner-joinwhere-clause

解决方案


首先:该if语句可能应该是一个while循环。

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

SELECT * FROM books INNER JOIN BOOK_TAGS ON tag_names=?

这缺少两个表之间的连接条件,因此只要其中至少一个具有搜索标签,这基本上会返回所有书籍。大概,你想要:

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 = ?
)

推荐阅读