Solved

SQL join 3 tables & show all rows from one

Posted on 2013-02-07
8
379 Views
Last Modified: 2013-02-15
Using mysql 5.5 but don't think that matters...

I have 3 tables

accounts
|a_id|StoreName|Address etc

products_accounts
|pa_id|p_fk|a_fk|

products
|p_id|UPC|ProdName| etc

some accounts have multiple products associated with them, some don't have any.

I need a query to return all accounts with associated products

result
----------------

a_id|StoreName | UPC | ProdName

1234 | Bob's Mart |12345 | WidgetA |
1235 | Bob's Mart |22345 | WidgetB |
1256 | Smart Mart |12345 | WidgetA |
3321 | Kwik Mart | null | null

I've tried a few combinations of left & right joins but can't seem to get it right.

I'm doing this in coldfusion so I can nest the product query within a store loop but Is this do-able with joins (or unions)??
0
Comment
Question by:SidFishes
8 Comments
 
LVL 6

Expert Comment

by:RustyZ32
ID: 38865660
SELECT t1.a_id, t1.storename, t3.upc, t3.prodname
FROM accounts t1
INNER JOIN products_accounts t2
ON t1.a_id = t2.a_fk
LEFT JOIN products t3
ON t2.p_fk = t3.p_id

 unless I am missing something about your tables that should return what you want.
0
 
LVL 15

Expert Comment

by:Aaron Shilo
ID: 38865672
select allaccounts
from accounts left join products  
ON t1.id = t2.id -- this will return all accounts , if you need
                          --you can more tables using the left join all the way.
union
select allaccounts
from accounts  join products ON t1.id = t2.id -- this will return accounts with products
0
 
LVL 36

Author Comment

by:SidFishes
ID: 38865759
Rusty, I basically had what you've posted, and I now realize (I think)  the reason it isn't working is that only accounts that have products associated with them are even -in- products_accounts table so the join can't work (as I was hoping)

I get products by accounts but if the account has no products associated with it, (ie: not in products_accounts table) then they don't show.

I think the only way to do this is in 2 parts. Unless someone has any other ideas.
0
Netscaler Common Configuration How To guides

If you use NetScaler you will want to see these guides. The NetScaler How To Guides show administrators how to get NetScaler up and configured by providing instructions for common scenarios and some not so common ones.

 
LVL 6

Accepted Solution

by:
RustyZ32 earned 500 total points
ID: 38865787
ok, I see what you mean, try this:



SELECT t1.a_id, t1.storename, t3.upc, t3.prodname
FROM accounts t1
INNER JOIN products_accounts t2
ON t1.a_id = t2.a_fk
LEFT JOIN products t3
ON t2.p_fk = t3.p_id

UNION

SELECT a_id, storename, NULL, NULL
FROM accounts t1
WHERE a_id NOT IN (SELECT a_fk FROM products_accounts)

ORDER BY  a_id
0
 
LVL 36

Author Comment

by:SidFishes
ID: 38866013
OK that's doing the trick...brutally slow however (28secs to return 15k rows). I guess that's the problem with Union?

If I was just returning 1 row it would be ok but I'm doing proximity lookups based on lat/lon and can have up to 50 store locations in an area.

Going to have to try something else I think. Unless you have any other suggestions, I'll award pts & close the q..
0
 
LVL 39

Expert Comment

by:appari
ID: 38866648
try this

Select a_id, StoreName ,  UPC ,  ProdName
from  accounts Left outer join products_accounts
on a_id =  a_fk
Left outer join products on p_id = p_fk
0
 
LVL 48

Expert Comment

by:PortletPaul
ID: 38866859
with table references included :-)
SELECT accounts.a_id, accounts.StoreName , products.UPC , products.ProdName
FROM accounts
LEFT OUTER JOIN products_accounts ON accounts.a_id = products_accounts.a_fk
LEFT OUTER JOIN products          ON products_accounts.p_fk = products.p_id

Open in new window

and, if there is potential for repeated account-product pairs then maybe:
SELECT accounts.a_id, accounts.StoreName , products.UPC , products.ProdName
FROM accounts
LEFT OUTER JOIN (
                   SELECT DISTINCT
                   products_accounts.a_fk, products_accounts.p_fk
                   FROM products_accounts
                ) ap              ON accounts.a_id = ap.a_fk
LEFT OUTER JOIN products          ON ap.p_fk = products.p_id

Open in new window

0
 
LVL 36

Author Comment

by:SidFishes
ID: 38895128
apologies...ended up using CF for the solution and forgot this was open.

Paul & appari - the left outer joins work, but they are even slower than the UNION (38 vs 28 seconds)

Pts to Rusty for first solution even though it's not practical in this instance due to the query time issue.
0

Featured Post

What is SQL Server and how does it work?

The purpose of this paper is to provide you background on SQL Server. It’s your self-study guide for learning fundamentals. It includes both the history of SQL and its technical basics. Concepts and definitions will form the solid foundation of your future DBA expertise.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article explains how to reset the password of the sa account on a Microsoft SQL Server.  The steps in this article work in SQL 2005, 2008, 2008 R2, 2012, 2014 and 2016.
These days, all we hear about hacktivists took down so and so websites and retrieved thousands of user’s data. One of the techniques to get unauthorized access to database is by performing SQL injection. This article is quite lengthy which gives bas…
This video shows how to set up a shell script to accept a positional parameter when called, pass that to a SQL script, accept the output from the statement back and then manipulate it in the Shell.
Via a live example, show how to set up a backup for SQL Server using a Maintenance Plan and how to schedule the job into SQL Server Agent.

838 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question