[英]In an SQL statement, how do you select all elements that are NOT a certain condition?
I'm sorry I formulated the question so badly--I'm new to programming. 抱歉,我这么糟糕地提出了这个问题-我是编程新手。
What I'm doing is, I'm using Java @NamedQuery in a little Library manager application. 我正在做的是,我在一个小的“库管理器”应用程序中使用Java @NamedQuery。 I have the entity class Book with attributes bookid, title, author, etc. and Bookstaken with attributes id, clientid, bookid, datetaken. 我有实体类Book,其属性为bookid,title,author等,而Bookstaken的属性为id,clientid,bookid,datetaken。 So Bookstaken.bookid is the foreign key that refers to Book.bookid. 因此,Bookstaken.bookid是引用Book.bookid的外键。 Bookstaken contains all the books that have been taken, and Book contains all the books that the library owns (but does not necessarily have at the moment). Bookstaken包含所有已获取的书籍,而Book包含图书馆拥有的所有书籍(但目前不一定有)。
I have fetched all Books that have been taken with this Named Query: 我已经赚得已经采取了这种命名查询所有书籍:
@NamedQuery(name = "Taken", query = "SELECT b FROM Book b, Bookstaken t WHERE b = t.bookid")
But now I want to make a Named Query called "Not taken" which will retrieve all books that have... you know, not been taken. 但是,现在我想进行一个名为“未采取”的命名查询,该查询将检索所有已经...未采取的书。 So essentially the complementary group of the query "Taken". 因此,本质上是查询“ Taken”的互补组。
I have tried this: 我已经试过了:
@NamedQuery(name = "Not taken", query = "SELECT b FROM Book b, Bookstaken t WHERE b <> t.bookid")
(and I've tried replacing <> with !=) (并且我尝试用<=替换<>)
But that statement is giving the entire group of Books, every single one of them, and giving that exact group multiple times. 但是这种说法是给整本书,每本书中的每一本书,都多次给出确切的书。 Why is this happening? 为什么会这样呢? I was never talented at SQL... And how can I fix it? 我从不具备SQL方面的才能...该如何解决呢?
Thanks 谢谢
First off, you should be certain of what you are comparing. 首先,您应该确定要比较的内容。 In: 在:
@NamedQuery(... "SELECT b FROM Book b, Bookstaken t WHERE b <> t.bookid")
You are comparing a Book
with an id ( Bookstaken.bookid
). 您正在将一Book
ID为( Bookstaken.bookid
)的Book
进行比较。 The latter probably is an Integer
, thus always different from a Book
. 后者可能是Integer
,因此总是与Book
不同。
By that rationale, you should use: "SELECT b FROM Book b, Bookstaken t WHERE b.bookid != t.bookid"
, as b != t.bookid
would return true
for all elements. 根据该原理,您应该使用: "SELECT b FROM Book b, Bookstaken t WHERE b.bookid != t.bookid"
,因为b != t.bookid
对于所有元素都将返回true
。
But that would probably not be just what you want. 但这可能不只是您想要的。 As rightfully pointed out in the comments, the above would result in a cartesian product. 正如评论中正确指出的那样,以上内容将导致笛卡尔积。 What you want is more along the lines of an SQL JOIN
, a LEFT OUTER JOIN
, to be more specific. 具体来说,您想要的更多是SQL JOIN
, LEFT OUTER JOIN
。
As in JPQL, LEFT JOIN
has actually the semantics of SQL's LEFT OUTER JOIN
, you could just use, then: 与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")
First of all, you have to realize that what you have here is not SQL, but JPQL. 首先,您必须意识到这里没有的是SQL,而是JPQL。 These are two different languages. 这是两种不同的语言。
Second, your query shows that you have a misconception. 其次,您的查询表明您有一个误解。 The BookTaken entity shouldn't have a bookid field. BookTaken实体不应具有bookid字段。 It should have a toOne association with Book, and thus a field of type Book. 它应该与Book有一个toOne关联,因此应该是一个Book类型的字段。
Finally, the query you have is not correct. 最后,您的查询不正确。 What you want is all the books for which there doesn't exist any BookTaken entity referencing this book: 您想要的是所有不存在引用此书的BookTaken实体的书:
select b from Book b where not exists (
select bt.id from BookTaken bt where bt.bookid = b.id)
You're approaching the query the wrong way. 您正在以错误的方式处理查询。 You're telling the database that you want all pairs of rows from Book
and Bookstaken
where the Bookstaken
doesn't match the Book
. 您正在告诉数据库,要让Book
and Bookstaken
中的所有行对都匹配Bookstaken
与Book
不匹配的行。 As you can imagine, there are lots of pairs of rows that don't match, so you're getting lots of rows, which is not what you want. 可以想象,有许多不匹配的行对,因此您会得到很多行,这不是您想要的。
What you really want is to select all rows in Book
that don't have a corresponding rown in Bookstaken
. 您真正想要的是选择Book
中所有没有在Bookstaken
没有相应行的行。 You can do this with 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 )
执行此操作SELECT b from Book WHERE NOT EXISTS( SELECT * from Bookstaken t WHERE t.bookid = b.bookid )
。
Or you can use a LEFT OUTER JOIN
to join Book
s to their matching Bookstaken
s but leave in the result set any Books
that don't have a corresponding Bookstaken
, and then use WHERE t.bookid = NULL
to get only the ones without a corresponding Bookstaken
. 或者你也可以使用LEFT OUTER JOIN
加入Book
s到与其相配套的Bookstaken
秒,但在结果集中留下任何Books
不具有相应的Bookstaken
,然后使用WHERE t.bookid = NULL
只得到没有的那些相应的Bookstaken
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.