简体   繁体   中英

Getting customers that have ordered two specific books from the database

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.

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