'MySQL subquery overview

Alright I am guessing I need a subquery to solve this and I am little rusty on these. So I have 3 tables:

tblAccount - Has User information and AccountID
tblItem - Has Item information and ItemID
tblAccountItem - Has 3 fields - AccountItemID / AccountID / ItemID

An account can have many items and an item can have many accounts. Example data:

tblAccount

AccountID    AccountName     AccountEmail
1            John Smith      [email protected]
2            Fred John       [email protected]
3            George Mike     [email protected]

tblItem

ItemID       ItemName        ItemDescription
1            Hammer          Smashes things
2            Axe             Breaks things

Ok so lets say the Hammer belongs to John,Fred and George. Axe only belongs to John and Fred.

tblAccountItem

AccountItemID       AccountID     ItemID
1                   1             1
2                   2             1
3                   3             1
4                   1             2
5                   2             2

So I want to show what items John has and also show who else owns that item. The output I want to show is:

ItemName            ItemDescription    OtherOwners
Hammer              Smashes things     Fred, George
Axe                 Breaks things      Fred

Any help would be greatly appreciated!

The answer by ctrahey is perfect but I have a slight condition to add. There are 2 types of accounts in tblAccount denoted by a field.

tblAccount

AccountID    AccountName     AccountEmail       AccountDescription    AccountTypeID
1            John Smith      [email protected]     NULL                  1
2            Fred John       [email protected]      NULL                  1
3            George Mike     [email protected]    Runner                2

tblAccountTypeID

AccountTypeID   AccountType     
1               User      
2               Admin     

If the AccountTypeID is 1 then I need to output the AccountEmail. If the AccountTypeID is 2 I need to output the AccountDescription. Eg output (same story as above):

ItemName            ItemDescription    OtherOwners
Hammer              Smashes things     Fred, Runner
Axe                 Breaks things      Fred

Going off the query that ctrahey I am guessing there needs to be an ALIAS field created. Something like:

WHERE AccountTypeID = 1 (SELECT AccountName)
WHERE AccountTypeID = 2 (SELECT AccountDescription)

I hope this makes sense, thanks for all the help so far!



Solution 1:[1]

Subqueries are very rarely actually needed, and are often replaced (with improved performance) by a well-designed JOIN.

Here, we start with AccountItem table (the WHERE clause immediately limits the query to only items owned by our account of interest); then we join the same table (aliasing it to 'others_items_join'), telling it to join with the same itemID but not owned by our account if interest. That's the essence of the entire query, the next two joins are only to bring in the actual strings we want to be in our output (the other people's names and the item names/descriptions). GROUP BY is used to give just one row per item which our account of interest has.

SELECT 
  ItemName,
  ItemDescription,
  GROUP_CONCAT(others.AccountName) as OtherOwners
FROM 
  tblAccountItem as my_items
  LEFT JOIN tblAccountItem as others_items_join 
    ON others_items_join.ItemID = my_items.ItemID AND others_items_join.AccountID != ?
  LEFT JOIN tblAccount as others
    ON others_items_join.AccountID = others.AccountID
  JOIN tblItems ON my_items.ItemID = tblItems.ItemID
WHERE my_items.AccountID = ?
GROUP BY ItemName

Solution 2:[2]

You better use a coding to resole this , here rough query that's may helps you get an idea :

SELECT AccountName
FROM tblAccount
WHERE AccountID = (SELECT AccoundID 
                   FROM tblAccountItem
                   WHERE itemID = (SELECT itemID
                                   FROM tblAccountItem
                                   WHERE AccountID = 1 (john Id as example)));

Hope this helps

Solution 3:[3]

SELECT ItemName, ItemDescription, AccountItemID FROM tblitem RIGHT JOIN tblaccountitem ON tblitem.ItemID=tblaccountitem.ItemID

I hope this helps lead to your answer. I am still looking into this

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Chris Trahey
Solution 2 RedhopIT
Solution 3 Henrey Bellchester