2014-01-24 24 views
1

考慮數據庫有這三個表獲取客戶,已下令兩個特定的書籍從數據庫中

BOOKID,ISBN,標題,URL,...)

客戶客戶ID,姓名,電子郵件,電話)

訂購BOOKID客戶ID,數量,日期)

我想要做的是,讓誰下令兩個特定圖書的客戶名爲"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
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」 和 「書B」 爲2,也就是即兩本書必須以相同的順序

如果你想尋找的書籍在同一客戶的任何命令,你需要的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中列舉它們並調整計數。

+2

這將返回客戶ID,如果他們訂購了Book A – Ghost

+0

@Ghost的兩份副本,我糾正了這一點,計算不同的'bookId'秒。 – FrankPl

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

謝謝你的回答,它的工作原理。我不知道有什麼辦法可以做到這一點,而不使用'EXISTS'? –

+0

是的,用'1 ='0123'替換'存在'' – alfasin

+0

@alfasin如果圖書被多次訂購,那麼用'1 ='替換'exists'將會失敗,因爲那麼子查詢會返回多行! – FrankPl