views:

103

answers:

2

Hi. Sorry for the horrible title, not sure how to explain this. I have a query that looks like this:

SELECT `name`, `latitude`, `longitude`, `indoor`, `address`,
    `phone`, `email`, `website`, `closed`
FROM rocks INNER JOIN 
    (SELECT DISTINCT id FROM rock_types WHERE type="DWS" or type="Top rope")
    AS types ON rocks.id=types.id
WHERE (latitude>-180 AND latitude<180) AND (longitude>-180 AND longitude<180)

In addition to what I'm getting right now, I'd like to get the list of types associated with each id. How can I do this? Thanks

+1  A: 

Here is my take using traditional join syntax:

SELECT rocks.name,
       rocks.latitude,
       rocks.longitude,
       rocks.indoor,
       rocks.address,
       rocks.phone,
       rocks.email,
       rocks.website,
       rocks.closed,
       rock_types.type

FROM   rocks,
       rock_types

WHERE  rocks.latitude  > -180                 AND
       rocks.latitude  < 180                  AND
       rocks.longitude > -180                 AND
       rocks.longitude < 180                  AND
       rocks.type_id   = rocks_types.id       AND
       rock_types.type IN ('DWS', 'Top rope')

The rocks.id = rocks_types.id does the link between both tables.

Here is how you can write the same query using INNER JOIN (both leads to the same result)

SELECT rocks.name,
       rocks.latitude,
       rocks.longitude,
       rocks.indoor,
       rocks.address,
       rocks.phone,
       rocks.email,
       rocks.website,
       rocks.closed,
       rock_types.type

FROM   rocks
       INNER JOIN rocks_types ON rocks.type_id = rocks_types.id

WHERE  rocks.latitude  > -180                 AND
       rocks.latitude  < 180                  AND
       rocks.longitude > -180                 AND
       rocks.longitude < 180                  AND
       rock_types.type IN ('DWS', 'Top rope')

EDIT: Based on your comment, the following will give you a comma separated list of types:

SELECT rocks.name,
       rocks.latitude,
       rocks.longitude,
       rocks.indoor,
       rocks.address,
       rocks.phone,
       rocks.email,
       rocks.website,
       rocks.closed,
       (SELECT    GROUP_CONCAT(DISTINCT rock_types.type SEPARATOR ',')
        FROM      rock_types
        WHERE     rock_types.id = rocks.id                AND
                  rock_types.type IN ('DWS', 'Top rope')
        GROUP BY  rock_types.id
       ) AS type

FROM   rocks

WHERE  rocks.latitude  > -180    AND
       rocks.latitude  < 180     AND
       rocks.longitude > -180    AND
       rocks.longitude < 180
Andrew Moore
thank you Andrew. This would work if every rock had only one type associated with. However, that is not always the case. The rocks table is a list of rocks indexed by id. The rock_types table map the id to 1 or more types so for example id=1 might have 2 rows in rock_types, 1 for DWS and 1 for top rope. This query will only return one of those. Is it possible to get all the types associated with that id?
bobbyb
Ahhh, should of included that in your original question. In which case, let me work this out.
Andrew Moore
I edited my question with the solution to your problem.
Andrew Moore
Thank you again Andrew. that did it!
bobbyb
A: 
SELECT `name`, `latitude`, `longitude`, `indoor`, `address`,
    `phone`, `email`, `website`, `closed`, 
    (SELECT GROUP_CONCAT(type SEPARATOR ',') FROM rock_types 
        WHERE (type="DWS" or type="Top rope") and  rock_types.id=rocks.id group by id) types
FROM rocks 
WHERE (latitude>-180 AND latitude<180) AND (longitude>-180 AND longitude<180)
ZA