Solved

SQL join 3 tables & show all rows from one

Posted on 2013-02-07
8
381 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
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
PeopleSoft Has Never Been Easier

PeopleSoft Adoption Made Smooth & Simple!

On-The-Job Training Is made Intuitive & Easy With WalkMe's On-Screen Guidance Tool.  Claim Your Free WalkMe Account Now

 
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 49

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

Get 15 Days FREE Full-Featured Trial

Benefit from a mission critical IT monitoring with Monitis Premium or get it FREE for your entry level monitoring needs.
-Over 200,000 users
-More than 300,000 websites monitored
-Used in 197 countries
-Recommended by 98% of users

Question has a verified solution.

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

Recently, Microsoft released a best-practice guide for securing Active Directory. It's a whopping 300+ pages long. Those of us tasked with securing our company’s databases and systems would, ideally, have time to devote to learning the ins and outs…
This post contains step-by-step instructions for setting up alerting in Percona Monitoring and Management (PMM) using Grafana.
Video by: Steve
Using examples as well as descriptions, step through each of the common simple join types, explaining differences in syntax, differences in expected outputs and showing how the queries run along with the actual outputs based upon a simple set of dem…
This videos aims to give the viewer a basic demonstration of how a user can query current session information by using the SYS_CONTEXT function

623 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