Database Management
 
Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
User Name:
Password:
Remember me
Go Back   Dev Shed ForumsDatabasesDatabase Management

Reply
Add This Thread To:
  Del.icio.us   Digg   Google   Spurl   Blink   Furl   Simpy   Y! MyWeb 
Thread Tools Search this Thread Rate Thread Display Modes
 
Unread Dev Shed Forums Sponsor:
  #1  
Old September 22nd, 2003, 03:45 AM
Jonathan_Beni Jonathan_Beni is offline
Junior Member
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Sep 2003
Posts: 3 Jonathan_Beni User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: < 1 sec
Reputation Power: 0
Generic "Many to Many" relationship question

Hi All!

I am sure that anyone new to databases has asked this question at one time, yet I still cannot find a decent answer… So, I’m trying here hoping someone can help…

OK, lets say I want a database that would eventually become an online catalog.
For the sake of simplicity, lets say the database initially has two tables:
Items and Categories.

ITEMS
ItemID (pk)
Item_name

CATEGORIES
CategoryID (pk)
Category_name

This is a many to many relationship:
(Each Item can be in several Categories && Each Category can contain several Items)

So, I define a composite table…

ITM_CAT
ItemID (pk)
CategoryID (pk)

SELECT * FROM itm_cat produces something like this:

ItemID CategoryID
1 1
2 1
3 1
3 2

So now I can find all Items WHERE CategoryID = x
Even WHERE CategoryID = x OR y

But how on earth can I extract those items WHERE CategoryID = x AND y?

Any assistance would be greatly appreciated.

Reply With Quote
  #2  
Old September 22nd, 2003, 06:28 AM
mitakeet's Avatar
mitakeet mitakeet is offline
Last Day: May 28, 2005
Dev Shed Demi-God (4500 - 4999 posts)
 
Join Date: Jul 2003
Location: Maryland
Posts: 4,575 mitakeet User rank is Sergeant (500 - 2000 Reputation Level)mitakeet User rank is Sergeant (500 - 2000 Reputation Level)mitakeet User rank is Sergeant (500 - 2000 Reputation Level)mitakeet User rank is Sergeant (500 - 2000 Reputation Level)mitakeet User rank is Sergeant (500 - 2000 Reputation Level) 
Time spent in forums: 1 Week 2 Days 9 h 49 m 59 sec
Reputation Power: 21
AND
Code:
select * from itm_cat
where CategoryID = 1
    and CategoryID = 2


OR

Code:
select * from itm_cat
where CategoryID = 1
    OR CategoryID = 2
__________________

Left DevShed May 28, 2005. Reason: Unresponsive administrators.
Free code: http://sol-biotech.com/code/.
Secure Programming: http://sol-biotech.com/code/SecProgFAQ.html.
Performance Programming: http://sol-biotech.com/code/PerformanceProgramming.html.

It is not that old programmers are any smarter or code better, it is just that they have made the same stupid mistake so many times that it is second nature to fix it.
--Me, I just made it up

The reasonable man adapts himself to the world; the unreasonable one persists in trying to adapt the world to himself. Therefore, all progress depends on the unreasonable man.
--George Bernard Shaw

Reply With Quote
  #3  
Old September 22nd, 2003, 08:44 AM
swampBoogie swampBoogie is online now
Contributing User
Dev Shed Intermediate (1500 - 1999 posts)
 
Join Date: Jan 2003
Location: Paris Uppland
Posts: 1,773 swampBoogie User rank is Sergeant Major (2000 - 5000 Reputation Level)swampBoogie User rank is Sergeant Major (2000 - 5000 Reputation Level)swampBoogie User rank is Sergeant Major (2000 - 5000 Reputation Level)swampBoogie User rank is Sergeant Major (2000 - 5000 Reputation Level)swampBoogie User rank is Sergeant Major (2000 - 5000 Reputation Level)swampBoogie User rank is Sergeant Major (2000 - 5000 Reputation Level) 
Time spent in forums: 2 Weeks 4 Days 14 h 8 m 8 sec
Reputation Power: 37
The and query

Code:
select  itemid from itm_cat
where CategoryID in (1,2)
group by itemid
having count(*) = 2


The one suggested in the previous post will never return any records.

Reply With Quote
  #4  
Old September 23rd, 2003, 02:26 AM
Jonathan_Beni Jonathan_Beni is offline
Junior Member
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Sep 2003
Posts: 3 Jonathan_Beni User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: < 1 sec
Reputation Power: 0
Thank you swampBoogie.
That works.

Ummm, how would I modify that query to return the Item_name from Items instead of ItemID from itm_cat?

Tried doing

Code:
select  item_name from items, itm_cat
where CategoryID in (1,2)
AND items.itemid = itm_cat.itemid
group by itemid
having count(*) = 2


but this returned no results...

Any suggestions?

Reply With Quote
  #5  
Old September 23rd, 2003, 06:49 AM
r937's Avatar
r937 r937 is offline
SQL Consultant
Click here for more information.
 
Join Date: Feb 2003
Location: Toronto Canada
Posts: 17,644 r937 User rank is General (90000 - 100000 Reputation Level)r937 User rank is General (90000 - 100000 Reputation Level)r937 User rank is General (90000 - 100000 Reputation Level)r937 User rank is General (90000 - 100000 Reputation Level)r937 User rank is General (90000 - 100000 Reputation Level)r937 User rank is General (90000 - 100000 Reputation Level)r937 User rank is General (90000 - 100000 Reputation Level)r937 User rank is General (90000 - 100000 Reputation Level)r937 User rank is General (90000 - 100000 Reputation Level)r937 User rank is General (90000 - 100000 Reputation Level)r937 User rank is General (90000 - 100000 Reputation Level)r937 User rank is General (90000 - 100000 Reputation Level)r937 User rank is General (90000 - 100000 Reputation Level)r937 User rank is General (90000 - 100000 Reputation Level)r937 User rank is General (90000 - 100000 Reputation Level)r937 User rank is General (90000 - 100000 Reputation Level) 
Time spent in forums: 1 Month 3 Weeks 6 Days 11 h 50 m
Reputation Power: 980
Code:
select item_name 
  from items
inner
  join itm_cat
    on items.itemID = itm_cat.itemID
 where itm_cat.CategoryID in (1,2)
group 
    by item_name
having count(*)=2
but this assumes itemID and item_name are 1:1, i.e. each item has a unique name

rudy
http://r937.com/

Reply With Quote
  #6  
Old September 23rd, 2003, 11:07 AM
Jonathan_Beni Jonathan_Beni is offline
Junior Member
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Sep 2003
Posts: 3 Jonathan_Beni User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: < 1 sec
Reputation Power: 0
I eventually figured it out and did it with a LEFT JOIN like so:
Code:
SELECT item_name FROM Items
LEFT JOIN itm_cat ON Items.itemid = itm_cat.itemid
WHERE itm_cat.catid IN ( 1, 2 )
GROUP BY itm_cat.imgID
HAVING COUNT( * ) = 2


It seems to work... Is there any significant difference between what was suggested in the previous post and this one?

Reply With Quote
  #7  
Old September 23rd, 2003, 12:45 PM
r937's Avatar
r937 r937 is offline
SQL Consultant
Click here for more information.
 
Join Date: Feb 2003
Location: Toronto Canada
Posts: 17,644 r937 User rank is General (90000 - 100000 Reputation Level)r937 User rank is General (90000 - 100000 Reputation Level)r937 User rank is General (90000 - 100000 Reputation Level)r937 User rank is General (90000 - 100000 Reputation Level)r937 User rank is General (90000 - 100000 Reputation Level)r937 User rank is General (90000 - 100000 Reputation Level)r937 User rank is General (90000 - 100000 Reputation Level)r937 User rank is General (90000 - 100000 Reputation Level)r937 User rank is General (90000 - 100000 Reputation Level)r937 User rank is General (90000 - 100000 Reputation Level)r937 User rank is General (90000 - 100000 Reputation Level)r937 User rank is General (90000 - 100000 Reputation Level)r937 User rank is General (90000 - 100000 Reputation Level)r937 User rank is General (90000 - 100000 Reputation Level)r937 User rank is General (90000 - 100000 Reputation Level)r937 User rank is General (90000 - 100000 Reputation Level) 
Time spent in forums: 1 Month 3 Weeks 6 Days 11 h 50 m
Reputation Power: 980
significant difference? depends on what you mean by "significant"

first of all, in any other database besides mysql, you must group by all non-aggregates in the SELECT list

i.e. you cannot select item_name and then group by itm_cat.imgID

secondly, LEFT OUTER doesn't make a difference, the query should produce the same results (bacuase the HAVING condition will throw out unmatched rows that the outer join might have returned), but performance-wise, it might be slower


rudy

Reply With Quote
Reply

Viewing: Dev Shed ForumsDatabasesDatabase Management > Generic "Many to Many" relationship question


Thread Tools  Search this Thread 
Search this Thread:

Advanced Search
Display Modes  Rate This Thread 
Rate This Thread:


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

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
View Your Warnings | New Posts | Latest News | Latest Threads | Shoutbox
Forum Jump


Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
  
 





© 2003-2008 by Developer Shed. All rights reserved. DS Cluster 1 hosted by Hostway