繁体   English   中英

在SQL语句中,如何选择非特定条件的所有元素?

[英]In an SQL statement, how do you select all elements that are NOT a certain condition?

抱歉,我这么糟糕地提出了这个问题-我是编程新手。

我正在做的是,我在一个小的“库管理器”应用程序中使用Java @NamedQuery。 我有实体类Book,其属性为bookid,title,author等,而Bookstaken的属性为id,clientid,bookid,datetaken。 因此,Bookstaken.bookid是引用Book.bookid的外键。 Bookstaken包含所有已获取的书籍,而Book包含图书馆拥有的所有书籍(但目前不一定有)。

我已经赚得已经采取了这种命名查询所有书籍:

@NamedQuery(name = "Taken", query = "SELECT b FROM Book b, Bookstaken t WHERE b = t.bookid")

但是,现在我想进行一个名为“未采取”的命名查询,该查询将检索所有已经...未采取的书。 因此,本质上是查询“ Taken”的互补组。

我已经试过了:

@NamedQuery(name = "Not taken", query = "SELECT b FROM Book b, Bookstaken t WHERE b <> t.bookid")

(并且我尝试用<=替换<>)

但是这种说法是给整本书,每本书中的每一本书,都多次给出确切的书。 为什么会这样呢? 我从不具备SQL方面的才能...该如何解决呢?

谢谢

首先,您应该确定要比较的内容。 在:

@NamedQuery(... "SELECT b FROM Book b, Bookstaken t WHERE b <> t.bookid")

您正在将一Book ID为( Bookstaken.bookid )的Book进行比较。 后者可能是Integer ,因此总是与Book不同。

根据该原理,您应该使用: "SELECT b FROM Book b, Bookstaken t WHERE b.bookid != t.bookid" ,因为b != t.bookid对于所有元素都将返回true


但这可能不只是您想要的。 正如评论中正确指出的那样,以上内容将导致笛卡尔积。 具体来说,您想要的更多是SQL JOINLEFT OUTER JOIN

与JPQL中一样, LEFT JOIN实际上具有SQL的LEFT OUTER JOIN的语义,您可以使用,然后:

@NamedQuery(name = "Not taken", query = 
"SELECT b FROM Book b LEFT JOIN Bookstaken t ON b.bookid = t.bookid "+
"WHERE t.bookid IS NULL")

首先,您必须意识到这里没有的是SQL,而是JPQL。 这是两种不同的语言。

其次,您的查询表明您有一个误解。 BookTaken实体不应具有bookid字段。 它应该与Book有一个toOne关联,因此应该是一个Book类型的字段。

最后,您的查询不正确。 您想要的是所有不存在引用此书的BookTaken实体的书:

select b from Book b where not exists (
    select bt.id from BookTaken bt where bt.bookid = b.id)

您正在以错误的方式处理查询。 您正在告诉数据库,要让Book and Bookstaken中的所有行对都匹配BookstakenBook不匹配的行。 可以想象,有许多不匹配的行对,因此您会得到很多行,这不是您想要的。

您真正想要的是选择Book中所有没有在Bookstaken没有相应行的行。 您可以使用SELECT b from Book WHERE NOT EXISTS( SELECT * from Bookstaken t WHERE t.bookid = b.bookid )执行此操作SELECT b from Book WHERE NOT EXISTS( SELECT * from Bookstaken t WHERE t.bookid = b.bookid )

或者你也可以使用LEFT OUTER JOIN加入Book s到与其相配套的Bookstaken秒,但在结果集中留下任何Books不具有相应的Bookstaken ,然后使用WHERE t.bookid = NULL只得到没有的那些相应的Bookstaken

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM