Consider a database has these three tables,
Book ( bookId , isbn, title, url, ... )
Customer ( customerId , name, email, phone)
Order ( bookId , customerId , quantity, date)
What i'm trying to do is, to get the customers who have ordered two specific books named "BOOK A"
and "BOOK B"
.
I came up with a query like this :
SELECT o.customerId
FROM Book b, Order o
WHERE o.bookId = b.bookId
AND b.title in ("BOOK A", "BOOK B");
Which resulted the customers who have ordered at least one of the two books i have specified.
Any help is appreciated.
SELECT o.customerId
FROM Book b, Order o
WHERE o.bookId = b.bookId
AND b.title in ("BOOK A")
AND EXISTS (select 1 from Book bb, Order oo
where oo.bookId = bb.bookId
and oo.customerId = o.customerId
and bb.title in ("BOOK B"))
SELECT o.customerId
FROM Order o
WHERE (SELECT count(distinct b.bookId)
FROM Book b
WHERE o.bookId = b.bookId
AND b.title in ('BOOK A', 'BOOK B')
) = 2;
This essentially checks that the number of books per order, restricted to "BOOK A" and "BOOK B" is 2, ie both books must be in the same order .
If you want to look for the books in any order of the same customer, you need a second instance of order
:
SELECT o.customerId
FROM Order o
WHERE (SELECT count(distinct b.bookId)
FROM Book b JOIN Order oo ON oo.bookId = b.bookId
WHERE o.customerId = oo.customerId
AND b.title in ('BOOK A', 'BOOK B')
) = 2;
This could be optimized, assuming a table Customer
:
SELECT c.customerId
FROM Customer c
WHERE (SELECT count(distinct b.bookId)
FROM Book b JOIN Order oo ON oo.bookId = b.bookId
WHERE c.customerId = oo.customerId
AND b.title in ('BOOK A', 'BOOK B')
) = 2;
This would avoid duplicate customers in the result, and join smaller tables, hence should be faster.
All three solutions can easily be extended to three, four ... books. Just enumerate them in the IN
and adapt the count.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.