Go Back   CodingForums.com > :: Server side development > MySQL

Before you post, read our: Rules & Posting Guidelines

Reply
 
Thread Tools Rate Thread
Enjoy an ad free experience by logging in. Not a member yet? Register.
Old 08-07-2012, 07:15 PM   PM User | #1
turpentyne
Regular Coder

 
Join Date: Aug 2010
Posts: 309
Thanks: 10
Thanked 1 Time in 1 Post
turpentyne is an unknown quantity at this point
join to narrow results?

I'm stumped on how to add in another joined table to get this query to narrow down my results. (hopefully I can explain this)

My starting point is the query below. For example, if $var = 1, the query pulls 3 results for example. I'm just showing the relevant info, The other columns are just data I need for printing to page:
tube, component_category: 1, comp_id = 1
quad, component_category: 1, comp_id = 2
comp, component_category: 1, comp_id = 3

Code:
SELECT tbl_component_categories.ID, tbl_component_categories.folder_path, tbl_component_categories.comp_cat_name, tbl_components.component_name, tbl_components.image_filepath, tbl_components.component_category, tbl_components.ID AS comp_id
FROM tbl_components JOIN tbl_component_categories ON tbl_components.component_category = tbl_component_categories.ID AND tbl_component_categories.ID = $var ORDER BY tbl_components.component_category
The table I want to join in is called tbl_component_to_component. I want to use this table to narrow down the results, based on a variable from a previous page where they chose from two options (having the id of 34 & 35, respectively)
But I can't figure out how to use that to narrow down my results. The table I want to include has three columns:
ID: Just a unique id,
component_ID: the id of components in tbl_components,
compatible_component_ID: the id of components in tbl_components that are compatible with the component in component_ID

As an example, relevant entries in this table are:

Code:
ID | component_ID | compatible_component_ID
---+--------------+---------------------------------
1  |    34        |  1
---+--------------+---------------------------------
2  |    34        | 2
---+--------------+---------------------------------
3  |    35        | 3
------------------------------------------------------
If they'd previously chosen an option with the id of 34 - which I'll pass as a variable - then I want the joined table to limit the query to 2 results based on that. If they chose an option with the id of 35, I want just the 1 matching result to pull.

The closest I've gotten to this, is the query below. If I set to id 34, I get all three results twice. If I set to 35, I get all results once.

Code:
SELECT tbl_component_categories.ID, tbl_component_categories.folder_path, tbl_component_categories.comp_cat_name, tbl_components.component_name, tbl_components.image_filepath, tbl_components.component_category, tbl_components.ID AS comp_id
FROM tbl_components
JOIN tbl_component_categories ON tbl_components.component_category = tbl_component_categories.ID
AND tbl_component_categories.ID =1
JOIN tbl_component_to_component ON 34 = tbl_component_to_component.component_ID
ORDER BY tbl_components.component_category
Good gawd! I hope that made at least some sense.
turpentyne is offline   Reply With Quote
Old 08-07-2012, 08:15 PM   PM User | #2
Old Pedant
Supreme Master coder!

 
Old Pedant's Avatar
 
Join Date: Feb 2009
Posts: 23,178
Thanks: 59
Thanked 3,995 Times in 3,964 Posts
Old Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to all
Well, with a many to many table (your component_to_component table...and why do you need a "tbl_" prefix when they are clearly tables?), the general rule is that you need to join to the "main" table twice.

So, for example, this would get you one record for each component_name AND matching compatible component_name:
Code:
SELECT C1.component_name, 
       C2.component_name AS compatibleComponentName
FROM tbl_components AS C1, 
     tbl_components AS C2,
     tbl_component_to_component AS CTC
WHERE C1.ID = CTC.component_ID
  AND C2.ID = CTC.compatible_component_id
ORDER BY C1.component_name, compatibleComponentName
So try to get that fixed in your head as the basic idea. (And notice how you can use ALIASES to make the code clearer! You must use at least one alias when a table is repeated in a query, in any case. So why not alias all the tables?)

Now... You can easily restrict that to only primary component ID #34 by either doing
Code:
SELECT C1.component_name, 
       C2.component_name AS compatibleComponentName
FROM tbl_components AS C1, 
     tbl_components AS C2,
     tbl_component_to_component AS CTC
WHERE C1.ID = CTC.component_ID
  AND C2.ID = CTC.compatible_component_id
  AND C1.ID = 34
ORDER BY C1.component_name, compatibleComponentName
or by doing
Code:
SELECT C1.component_name, 
       C2.component_name AS compatibleComponentName
FROM tbl_components AS C1, 
     tbl_components AS C2,
     tbl_component_to_component AS CTC
WHERE C1.ID = CTC.component_ID
  AND C2.ID = CTC.compatible_component_id
  AND CTC.component_ID = 34
ORDER BY C1.component_name, compatibleComponentName
Hopefully you can see those two are identical, of necessity, because of the
Code:
    WHERE C1.ID = CTC.component_ID
condition.

So now all you have to do is join in your component_categories table:
Code:
SELECT CAT.ID, CAT.folder_path, CAT.comp_cat_name, 
       C1.component_name, C1.image_filepath, C1.component_category, C1.ID AS comp_id,
       C2.component_name AS compatibleComponentName
FROM tbl_components AS C1, 
     tbl_components AS C2,
     tbl_component_to_component AS CTC,
     tbl_component_categories AS CAT
WHERE C1.ID = CTC.component_ID
  AND C2.ID = CTC.compatible_component_id
  AND C1.component_category = CAT.ID
  AND CAT.ID = 1
  AND C1.ID = 34
ORDER BY C.component_category, C2.compatibleComponentName
Note that of course you don't *need* to select any fields from C2. But then what was the point in getting the component_to_component table involved in the first place?

If you don't need to know ANYTHING about the compatible components, then what was wrong with simply doing
Code:
SELECT CAT.ID, CAT.folder_path, CAT.comp_cat_name, 
       C1.component_name, C1.image_filepath, C1.component_category, C1.ID AS comp_id
FROM tbl_components AS C1, 
     tbl_component_categories AS CAT
WHERE C1.component_category = CAT.ID
  AND CAT.ID = 1
  AND C1.ID = 34
ORDER BY C.component_category
???

Unless, of course, I have misunderstand your table relationships. It would help if you'd name fields the same when they appear in more than one table.

As a general rule, I *NEVER* name anything just "ID". (And I never put "tbl_" on table names.)

I would have done
Code:
CREATE TABLE components (
    component_ID INT AUTO_INCREMENT PRIMARY KEY,
    category_ID INT REFERENCES component_categories(category_ID)
    component_name VARCHAR(xxx), 
    ... etc. ...
);

CREATE TABLE component_categories (
    category_ID INT AUTO_INCREMENT PRIMARY KEY,
    category_name VARCHAR(xxx),
    ... etc. ...
);
So that then I get a NATURAL join between the components table and the component_to_component table, using the same field name. And ditto the join to component_categories.
__________________
An optimist sees the glass as half full.
A pessimist sees the glass as half empty.
A realist drinks it no matter how much there is.
Old Pedant is online now   Reply With Quote
Old 08-07-2012, 08:16 PM   PM User | #3
turpentyne
Regular Coder

 
Join Date: Aug 2010
Posts: 309
Thanks: 10
Thanked 1 Time in 1 Post
turpentyne is an unknown quantity at this point
whoah.. wait.. I might've figured it out:

PHP Code:
SELECT DISTINCT tbl_component_to_component.component_IDtbl_component_to_component.compatible_component_IDtbl_component_categories.IDtbl_component_categories.folder_pathtbl_component_categories.comp_cat_nametbl_components.component_nametbl_components.image_filepathtbl_components.component_categorytbl_components.ID AS comp_id
FROM tbl_components
JOIN tbl_component_categories ON tbl_components
.component_category tbl_component_categories.ID
AND tbl_component_categories.ID =1
JOIN tbl_component_to_component ON 34 
tbl_component_to_component.component_ID AND tbl_components.ID tbl_component_to_component.compatible_component_ID 
turpentyne is offline   Reply With Quote
Reply

Bookmarks

Jump To Top of Thread


Thread Tools
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

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 09:57 PM.


Advertisement
Log in to turn off these ads.