从数据库中订购已订购两本特定书籍的客户

时间:2014-01-24 00:47:46

标签: sql

考虑一个数据库有这三个表,

  

预订 bookId ,isbn,title,url,...)

     

客户 customerId ,姓名,电子邮件,电话)

     

订单 bookId customerId ,数量,日期)

我想要做的是,让订购了两本名为"BOOK A""BOOK B"的特定图书的客户。

我提出了这样的查询:

SELECT o.customerId
FROM Book b, Order o
WHERE o.bookId = b.bookId
AND  b.title in ("BOOK A", "BOOK B");

导致客户订购了至少一本我指定的两本书。

感谢任何帮助。

2 个答案:

答案 0 :(得分:2)

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"))

答案 1 :(得分:2)

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;

这基本上检查每个订单的书籍数量,限于“BOOK A”和“BOOK B”是2,i。即这两本书的顺序必须相同

如果您想以同一客户的任何顺序查找图书,则需要第二个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;

假设表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;

这样可以避免结果中的重复客户,并加入较小的表,因此应该更快。

所有这三种解决方案都可以轻松扩展到三本,四本......书籍。只需在IN中枚举它们并调整计数。