views:

39

answers:

1

Assume I have these tables, from which i need to display search results in a browser:

Table: Containers

id   |   name
1      Big Box
2      Grocery Bag
3      Envelope
4      Zip Lock


Table: Sale

id  | date     | containerid
1     20100101   1
2     20100102   2
3     20091201   3
4     20091115   4


Table: Items

id  |  name        | saleid
1      Barbie Doll   1
2      Coin          3
3      Pop-Top       4
4      Barbie Doll   2
5      Coin          4

I need output that looks like this:

itemid  itemname     saleids      saledates       containerids     containertypes
1       Barbie Doll    1,2    20100101,20100102       1,2       Big Box, Grocery Bag
2       Coin           3,4    20091201,20091115       3,4       Envelope, Zip Lock
3       Pop-Top         4          20091115            4              Zip Lock

The important part is that each item type only gets one record/row in the return on the screen. I accomplished this in the past by returning multiple rows of the same item and using a scripting language to limit the output. However, this makes the ui overly complicated and loopy. So, I'm hoping I can get the database to spit out only as many records as there are rows to display.

This example may be a bit extreme because of the 2 joins needed to get to the container from the item (through the sale table).

I'd be happy for just an example query that outputs this:

itemid  itemname     saleids      saledates    
1       Barbie Doll    1,2    20100101,20100102  
2       Coin           3,4    20091201,20091115   
3       Pop-Top         4          20091115       

I can only return a single result in a subquery, so I'm not sure how to do this.

+2  A: 

Assuming you're using MySQL (of the four questions you have, only one is tagged as MySQL), the GROUP_CONCAT function is what you're after:

  SELECT i.name AS itemname,
         GROUP_CONCAT(s.id ORDER BY s.id) AS salesids,
         GROUP_CONCAT(s.date ORDER BY s.date) AS salesdates,
         GROUP_CONCAT(s.containerid ORDER BY s.containerid) AS containerids,
         GROUP_CONCAT(c.name ORDER BY c.name) AS containertypes
    FROM ITEMS i
    JOIN SALE s ON s.id = i.salesid
    JOIN CONTAINERS c ON c.id = s.containerid
GROUP BY i.name

If you want items that might not have links to the SALES and/or CONTAINERS tables - add "LEFT" in front of the "JOIN".

OMG Ponies
this works perfect except that the group by should just be i.name (to avoid duplicate rows of the same item name).Thank you for this excellent answer.
Todd
Thar ya go, sir (or ma'am).
Todd
@Todd: You mean "Stallion" or "Mare" - certainly not gelding :) http://wiki.answers.com/Q/Other_gender_for_horse
OMG Ponies