Go Back   SitePoint Forums > Forum Index > Program Your Site > Databases
Newsletter FAQ Members List Calendar Mark Forums Read

New to SitePoint Forums? Register here for free!

SitePoint Sponsor
 
Reply
 
Thread Tools Display Modes
Old Jul 8, 2005, 10:08   #1
philwilks
SitePoint Enthusiast
 
Join Date: May 2004
Location: Salisbury, UK
Posts: 55
Help needed with "many-to-many" select statement

I have three tables:

  • products (prodId, prodName, description, price)
  • classifications (classId, className)
  • junctions (prodId, classId)
The products table stores the details of various t-shirts.

The classifications table stores all of the differant attributes that a t-shirt might have. For example: Small, Medium, Large, Black, White, Blue, Pink, V-neck, Round neck, Short sleeved, Long sleeved etc.

The junctions table sets up a many-to-many relationship between products and classifications. The idea is that any given t-shirt in the products table could have any number of the attributes in the classifications table. For example, one t-shirt could be available in two different sizes and three different colors.

I want to set up a system so that the user can choose a range of classifications, and then filter the products table accordingly to show which t-shirts match their criteria. A typical requirement might be:

Large and (White or Pink) and V-neck

Any suggestions? I have everything else set up fine, I'm just struggling with formulating an SQL SELECT statement to do the query.

Last edited by philwilks; Jul 8, 2005 at 11:55.
philwilks is offline   Reply With Quote
Old Jul 8, 2005, 13:27   #2
Tangerine_Dream
SitePoint Evangelist
 
Join Date: Apr 2005
Location: Moscow, Russia
Posts: 559
Hi, maybe this will help:

Code:
SELECT p.prodName, p.description, p.price FROM products p
  INNER JOIN junctions j ON p.prodId = j.prodId
  INNER JOIN classifications c ON j.classId = c.classId 
  WHERE c.className = 'Large' AND c.className = 'V-neck' AND ( c.className = 'White' OR c.className = 'Pink'  );
Tangerine_Dream is offline   Reply With Quote
Old Jul 8, 2005, 17:37   #3
r937
SQL Consultant
silver trophybronze trophy
SitePoint Award Recipient
 
r937's Avatar
 
Join Date: Jul 2002
Location: Toronto, Canada
Posts: 31,026
Quote:
Originally Posted by Tangerine_Dream
Code:
  WHERE c.className = 'Large' AND c.className = 'V-neck'
that's never going to return anything!!!

r937 is online now   Reply With Quote
Old Jul 8, 2005, 17:42   #4
r937
SQL Consultant
silver trophybronze trophy
SitePoint Award Recipient
 
r937's Avatar
 
Join Date: Jul 2002
Location: Toronto, Canada
Posts: 31,026
this should work for the given example (since presumably an item cannot be both white and pink) --
Code:
select p.prodName
     , p.description
     , p.price 
  from products p
inner 
  join junctions j 
    on p.prodId = j.prodId
inner 
  join classifications c 
    on j.classId = c.classId 
group
    by p.prodName
     , p.description
     , p.price 
having sum(case when c.className 
             in ('Large','V-neck','White','Pink')
                then 1 else 0 end)
       = 3
however, you might want to think about how to generalize this a bit more for an arbitrary set of AND/OR search conditions
r937 is online now   Reply With Quote
Old Jul 9, 2005, 02:42   #5
philwilks
SitePoint Enthusiast
 
Join Date: May 2004
Location: Salisbury, UK
Posts: 55
Thank you both for your advise!

Tangerine Dream: Rudy is right - your query will never return anything. This is exactly what I tried to begin with, before I posted on this forum.

Rudy: I think you have grasped my problem - thank you very much for your example code! Unfortunately, I cannot assume that an item will not be both white and pink. For example, a "Bart Simpson" t-shirt might be available in Child, Small and Medium sizes, and in Blue, White or Pink.

Any ideas?!?

PS: I should have explained that I will be filtering the database using classId, not className. I only used the name in my question to make my problem easier to understand. Anyway, that's not a big deal.
philwilks is offline   Reply With Quote
Old Jul 9, 2005, 03:21   #6
r937
SQL Consultant
silver trophybronze trophy
SitePoint Award Recipient
 
r937's Avatar
 
Join Date: Jul 2002
Location: Toronto, Canada
Posts: 31,026
okay, then
Code:
having sum(case when c.className 
             in ('Large','V-neck')
                then 1 else 0 end)
       = 2          
   and sum(case when c.className 
             in ('White','Pink') 
                then 1 else 0 end)
       > 0
r937 is online now   Reply With Quote
Reply

Bookmarks

« Previous Thread | Next Thread »

Thread Tools
Display Modes

 
Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Sponsored Links
 
Forum Jump


All times are GMT -7. The time now is 18:22.


Powered by vBulletin® Version 3.7.1
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.
Copyright 1998-2009, SitePoint Pty Ltd. All Rights Reserved