MySQL Help
 
Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
User Name:
Password:
Remember me
Go Back   Dev Shed ForumsDatabasesMySQL Help

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 June 25th, 2009, 02:56 PM
almo2001 almo2001 is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Mar 2009
Posts: 99 almo2001 User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 1 Day 5 h 8 m 46 sec
Reputation Power: 1
Three table join problem

Hi!

I have three tables:

tbl_hordepacks (H):
hordepack_id user_id name

tbl_hordepacks_creatures (HC):
hordepack_id creature_id count

tbl_user_collection_creatures (UCC):
user_id creature_id count

Given a hordepack_id and a creature_id, I want the count in the hordepack and the collection.

So I need count from HC (easy) and count from UCC where creature_id matches the given one and the user_id matches the user_id of the given hordepack_id.

I keep getting weird results that look like there's a problem doing

SELECT hc.count AS packcount, ucc.count AS collectioncount.

Do I need to do two different queries? My instinct is that there's a single query that will do this, but I'm really having a hard time finding it.

Here's my current attempt:

Code:
SELECT hc.count AS packcount, ucc.count AS collectioncount
FROM tbl_hordepacks_creatures AS hc
JOIN tbl_user_collection_creatures AS ucc
	ON hc.creature_id = ucc.creature_id
JOIN tbl_hordepacks AS h
	ON h.user_id = ucc.user_id
WHERE h.user_id = 1 AND h.hordepack_id = 1 AND hc.creature_id = 128


But this returns every count from HC without restricting by hordepack_id or user_id.

UPDATE:

Code:
SELECT hc.count AS packcount, ucc.count AS collectioncount
FROM tbl_hordepacks_creatures AS hc
JOIN tbl_user_collection_creatures AS ucc
	ON hc.creature_id = ucc.creature_id
JOIN tbl_hordepacks AS h
	ON h.user_id = ucc.user_id
WHERE h.user_id = 1 AND hc.hordepack_id = 1 AND ucc.creature_id = 128


This returns the correct result, but twice. I'm pretty sure I don't fully understand what's going on when I JOIN twice.

Last edited by almo2001 : June 25th, 2009 at 03:05 PM.

Reply With Quote
  #2  
Old June 26th, 2009, 07:12 AM
srisa srisa is offline
Contributing User
Dev Shed Beginner (1000 - 1499 posts)
 
Join Date: May 2006
Location: I'm sneaking up behind you.
Posts: 1,205 srisa User rank is Captain (20000 - 30000 Reputation Level)srisa User rank is Captain (20000 - 30000 Reputation Level)srisa User rank is Captain (20000 - 30000 Reputation Level)srisa User rank is Captain (20000 - 30000 Reputation Level)srisa User rank is Captain (20000 - 30000 Reputation Level)srisa User rank is Captain (20000 - 30000 Reputation Level)srisa User rank is Captain (20000 - 30000 Reputation Level)srisa User rank is Captain (20000 - 30000 Reputation Level)srisa User rank is Captain (20000 - 30000 Reputation Level) 
Time spent in forums: 3 Weeks 47 m 4 sec
Reputation Power: 250
Try this
sql Code:
Original - sql Code
  1.  
  2. SELECT hc.COUNT AS packcount, ucc.COUNT AS collectioncount
  3. FROM tbl_hordepacks_creatures AS hc
  4. JOIN tbl_user_collection_creatures AS ucc
  5.     ON (hc.creature_id = ucc.creature_id
  6.        AND hc.creature_id = 128
  7.        AND hc.hordepack_id = 1)
  8. JOIN tbl_hordepacks AS h
  9.     ON (h.hordepack_id = hc.hordepack_id
  10.        AND h.user_id = ucc.user_id
  11.        AND h.user_id = 1)
Comments on this post
almo2001 agrees: Seems to work, thanks!
__________________
Why do we always seek someone, something or some thought, are we afraid of ourselves?
I never thought that i would be this handsome hunk with beautiful models hanging all over my joints; thank God i didn't, 'coz it never happened. - Anonymous

Reply With Quote
  #3  
Old June 26th, 2009, 10:20 AM
r937's Avatar
r937 r937 is offline
SQL Consultant
Click here for more information.
 
Join Date: Feb 2003
Location: Toronto Canada
Posts: 20,792 r937 User rank is General 22nd Grade (Above 100000 Reputation Level)r937 User rank is General 22nd Grade (Above 100000 Reputation Level)r937 User rank is General 22nd Grade (Above 100000 Reputation Level)r937 User rank is General 22nd Grade (Above 100000 Reputation Level)r937 User rank is General 22nd Grade (Above 100000 Reputation Level)r937 User rank is General 22nd Grade (Above 100000 Reputation Level)r937 User rank is General 22nd Grade (Above 100000 Reputation Level)r937 User rank is General 22nd Grade (Above 100000 Reputation Level)r937 User rank is General 22nd Grade (Above 100000 Reputation Level)r937 User rank is General 22nd Grade (Above 100000 Reputation Level)r937 User rank is General 22nd Grade (Above 100000 Reputation Level)r937 User rank is General 22nd Grade (Above 100000 Reputation Level)r937 User rank is General 22nd Grade (Above 100000 Reputation Level)r937 User rank is General 22nd Grade (Above 100000 Reputation Level)r937 User rank is General 22nd Grade (Above 100000 Reputation Level)r937 User rank is General 22nd Grade (Above 100000 Reputation Level) 
Time spent in forums: 2 Months 1 Week 3 Days 20 h 24 m 10 sec
Reputation Power: 2482
i'd like to suggest a slight change to the query

the first table in the FROM clause should be the "driving" table, such that it determines the fewest rows to be joined to the other tables

thus, conditions on the driving table belong in the WHERE clause, and all other conditions can/should be added to their respective ON clauses
Code:
SELECT hc.COUNT AS packcount
     , ucc.COUNT AS collectioncount
  FROM tbl_hordepacks_creatures AS hc
INNER
  JOIN tbl_user_collection_creatures AS ucc
    ON ucc.creature_id = hc.creature_id
INNER
  JOIN tbl_hordepacks AS h
    ON h.hordepack_id = hc.hordepack_id 
   AND h.user_id = ucc.user_id
   AND h.user_id = 1
 WHERE hc.creature_id = 128
   AND hc.hordepack_id = 1
__________________
r937.com | rudy.ca
please visit Simply SQL and buy my book

Reply With Quote
  #4  
Old June 26th, 2009, 04:28 PM
srisa srisa is offline
Contributing User
Dev Shed Beginner (1000 - 1499 posts)
 
Join Date: May 2006
Location: I'm sneaking up behind you.
Posts: 1,205 srisa User rank is Captain (20000 - 30000 Reputation Level)srisa User rank is Captain (20000 - 30000 Reputation Level)srisa User rank is Captain (20000 - 30000 Reputation Level)srisa User rank is Captain (20000 - 30000 Reputation Level)srisa User rank is Captain (20000 - 30000 Reputation Level)srisa User rank is Captain (20000 - 30000 Reputation Level)srisa User rank is Captain (20000 - 30000 Reputation Level)srisa User rank is Captain (20000 - 30000 Reputation Level)srisa User rank is Captain (20000 - 30000 Reputation Level) 
Time spent in forums: 3 Weeks 47 m 4 sec
Reputation Power: 250
Quote:
Originally Posted by r937
i'd like to suggest a slight change to the query

the first table in the FROM clause should be the "driving" table, such that it determines the fewest rows to be joined to the other tables

thus, conditions on the driving table belong in the WHERE clause, and all other conditions can/should be added to their respective ON clauses

So, the rows from the table in the FROM clause are first retrieved based on the WHERE clause (if given) and then the JOIN's are performed.
Is that correct?

Reply With Quote
  #5  
Old June 26th, 2009, 05:29 PM
r937's Avatar
r937 r937 is offline
SQL Consultant
Click here for more information.
 
Join Date: Feb 2003
Location: Toronto Canada
Posts: 20,792 r937 User rank is General 22nd Grade (Above 100000 Reputation Level)r937 User rank is General 22nd Grade (Above 100000 Reputation Level)r937 User rank is General 22nd Grade (Above 100000 Reputation Level)r937 User rank is General 22nd Grade (Above 100000 Reputation Level)r937 User rank is General 22nd Grade (Above 100000 Reputation Level)r937 User rank is General 22nd Grade (Above 100000 Reputation Level)r937 User rank is General 22nd Grade (Above 100000 Reputation Level)r937 User rank is General 22nd Grade (Above 100000 Reputation Level)r937 User rank is General 22nd Grade (Above 100000 Reputation Level)r937 User rank is General 22nd Grade (Above 100000 Reputation Level)r937 User rank is General 22nd Grade (Above 100000 Reputation Level)r937 User rank is General 22nd Grade (Above 100000 Reputation Level)r937 User rank is General 22nd Grade (Above 100000 Reputation Level)r937 User rank is General 22nd Grade (Above 100000 Reputation Level)r937 User rank is General 22nd Grade (Above 100000 Reputation Level)r937 User rank is General 22nd Grade (Above 100000 Reputation Level) 
Time spent in forums: 2 Months 1 Week 3 Days 20 h 24 m 10 sec
Reputation Power: 2482
Quote:
Originally Posted by srisa
So, the rows from the table in the FROM clause are first retrieved based on the WHERE clause (if given) and then the JOIN's are performed.
Is that correct?
um, sort of

i hope i did not give the impression that you can influence the sequence of execution by what you put into the WHERE clause for the first table in the JOIN

you actually can dictate the sequence of join (with special keywords), but this is rarely a good idea

the database optimizer will figure out the best execution sequence based on the logical construction of the query requirements, examining all the different ways of doing it, and choosing the fastest

... and it's way better at that than we SQL developers are

all i wanted to say was that with a little bit of thought, it's pretty easy to tell in any given situation (and i've seen thousands of them) which table is the driving table

so you write the query in that manner, thus adding ~immensely~ to the value of the SQL itself as a means of documention wtf the query is doing

have you ever come back to a complex query several months later, and wished you knew what it was doing and why?

that's what coding style is all about

Reply With Quote
  #6  
Old June 29th, 2009, 02:50 PM
almo2001 almo2001 is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Mar 2009
Posts: 99 almo2001 User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 1 Day 5 h 8 m 46 sec
Reputation Power: 1
Quote:
Originally Posted by r937
i'd like to suggest a slight change to the query

the first table in the FROM clause should be the "driving" table, such that it determines the fewest rows to be joined to the other tables

thus, conditions on the driving table belong in the WHERE clause, and all other conditions can/should be added to their respective ON clauses
Code:
SELECT hc.COUNT AS packcount
     , ucc.COUNT AS collectioncount
  FROM tbl_hordepacks_creatures AS hc
INNER
  JOIN tbl_user_collection_creatures AS ucc
    ON ucc.creature_id = hc.creature_id
INNER
  JOIN tbl_hordepacks AS h
    ON h.hordepack_id = hc.hordepack_id 
   AND h.user_id = ucc.user_id
   AND h.user_id = 1
 WHERE hc.creature_id = 128
   AND hc.hordepack_id = 1


Ok, I think I get it. Thanks a lot for the help!

ETA: one question: is "AND h.user_id = 1" redundant? As long as h.user_id matches ucc.user_id, it should be fine since ucc_user_id must be 1 since user 1 owns that pack...

Last edited by almo2001 : June 29th, 2009 at 03:08 PM.

Reply With Quote
  #7  
Old June 29th, 2009, 03:32 PM
r937's Avatar
r937 r937 is offline
SQL Consultant
Click here for more information.
 
Join Date: Feb 2003
Location: Toronto Canada
Posts: 20,792 r937 User rank is General 22nd Grade (Above 100000 Reputation Level)r937 User rank is General 22nd Grade (Above 100000 Reputation Level)r937 User rank is General 22nd Grade (Above 100000 Reputation Level)r937 User rank is General 22nd Grade (Above 100000 Reputation Level)r937 User rank is General 22nd Grade (Above 100000 Reputation Level)r937 User rank is General 22nd Grade (Above 100000 Reputation Level)r937 User rank is General 22nd Grade (Above 100000 Reputation Level)r937 User rank is General 22nd Grade (Above 100000 Reputation Level)r937 User rank is General 22nd Grade (Above 100000 Reputation Level)r937 User rank is General 22nd Grade (Above 100000 Reputation Level)r937 User rank is General 22nd Grade (Above 100000 Reputation Level)r937 User rank is General 22nd Grade (Above 100000 Reputation Level)r937 User rank is General 22nd Grade (Above 100000 Reputation Level)r937 User rank is General 22nd Grade (Above 100000 Reputation Level)r937 User rank is General 22nd Grade (Above 100000 Reputation Level)r937 User rank is General 22nd Grade (Above 100000 Reputation Level) 
Time spent in forums: 2 Months 1 Week 3 Days 20 h 24 m 10 sec
Reputation Power: 2482
Quote:
Originally Posted by almo2001
...since ucc_user_id must be 1 since user 1 owns that pack...
hmmmm.....

Reply With Quote
  #8  
Old June 29th, 2009, 03:42 PM
almo2001 almo2001 is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Mar 2009
Posts: 99 almo2001 User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 1 Day 5 h 8 m 46 sec
Reputation Power: 1
Quote:
Originally Posted by r937
hmmmm.....


WHERE hc.creature_id = 128 AND hc.hordepack_id = 1

One hordepack belongs to one user. So once we specify hordepack_id = 1, we have effectively specified the user since tbl_hordepacks has hordepack_id, user_id, and name.

I've tried removing WHERE user_id = 1 and it seems to work the same.

Reply With Quote
Reply

Viewing: Dev Shed ForumsDatabasesMySQL Help > Three table join problem


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




 Free IT White Papers!
 
How to Present Effectively Online
This white paper offers practical and actionable advice on the key steps that any presenter should consider as they plan and execute a Webinar or online meeting.

 
Open Source Security Myths
Open Source Software (OSS) is computer software whose source code is available to the general public with relaxed or non-existent intellectual property restrictions (or arrangement such as the public domain), and is usually developed with the input of many contributors.

 
Power and Cooling Capacity Management for Data Centers
This paper describes the principles for achieving power and cooling capacity management.

 
Scalable, Fault-Tolerant NAS for Oracle - The Next Generation
For several years NAS has been evolving as a storage alternative for Oracle databases, and for good reason: NAS is quite often the simplest, most cost-effective storage approach for Oracle. Learn about the benefits that HP's approach to scalable NAS brings to Oracle environments in this comprehensive white paper.

 
Understanding Web Application Security Challenges
This white paper discusses many common threats and preventive measures for Web application security, and explains what you can do to help protect your organization.

 

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




© 2003-2009 by Developer Shed. All rights reserved. DS Cluster 3 Hosted by Hostway
For more Enterprise Application Development news, visit eWeek