|  | Posted by Erland Sommarskog on 04/14/07 10:49 
(tizmagik@gmail.com) writes:> Database consists of the following 4 tables with respective
 > attributes:
 >
 > CUSTOMER(C#, CUSTOMER NAME, ADDRESS), the key is [C#]
 > ITEM(I#, ITEM NAME, MANUFACTURER, YEAR), the key is [I#]
 > BOUGHT(C#, I#, DATE, QUANTITY), the key is [C#, I#,DATE]
 > PREFER(I#, C#), the key is [I#, C#]
 >
 > I'm trying to construct the following query (in SQL)
 >
 > List of customers that bought all the items that John prefers.
 >
 > I can get the list of all the items that John prefers, but I'm not
 > sure how to check that list against customers who bought ALL those
 > items. I'm assuming it's either a division or some sort of subtraction
 > but I'm not sure how to formulate the SQL query.
 
 This smells of class assignment, but OK, let's go for it anyway.
 
 If memory serves this is something they for some reason I've never
 understood call relational division. In less occluded terms, a HAVING
 clause can shortcut the need for a couple of EXISTS and NOT EXISTS.
 
 SELKCT C.C#, C.CUSTOMER_NAME
 FROM   CUSTOMER C
 JOIN   (SELECT B.C#
 FROM   BOUGHT B
 GROUP  BY B.C#
 HAVING COUNT(DISTINCT B.I#) =
 (SELECT COUNT(*)
 FROM   PREFER P
 JOIN   CUSTOMER C ON P.C# = C.C#
 WHERE  C.CUSTOMER_NAME = 'John')) AS res
 ON C.C# = res.C#
 
 --
 Erland Sommarskog, SQL Server MVP, esquel@sommarskog.se
 
 Books Online for SQL Server 2005 at
 http://www.microsoft.com/technet/prodtechnol/sql/2005/downloads/books.mspx
 Books Online for SQL Server 2000 at
 http://www.microsoft.com/sql/prodinfo/previousversions/books.mspx
 [Back to original message] |