Tycho
Tycho

Reputation: 48

Join rows with different column values

I'm making a search engine with a possibility to use filters.

My SQL looks like this;

SELECT l.location_id, og.*,f.*
        FROM object_types ot
        LEFT JOIN object_group_types ogt ON ogt.object_type_id = ot.object_type_id
        LEFT JOIN object_groups og ON og.object_group_type_id = ogt.object_group_type_id
        LEFT JOIN object_groups2filters og2f ON og2f.object_group_id = og.object_group_id
        LEFT JOIN filters f ON f.filter_id = og2f.filter_id
        LEFT JOIN locations l ON l.location_id = og.location_id
        WHERE ot.object_type_key = 'TYPE_TENNIS';

Now based on the users filter input I want to select the right location for it. But because I join everything with a LEFT JOIN, I get all the filter items on different rows, see picture.

enter image description here

So I want to select a location where a location_id has both filter_key FILTER_GRASS and FILTER_PARKING.

If I use "AND f.filter_key = 'FILTER_PARKING' AND f.filter_key = 'FILTER_GRASS'", it will not work because the filter values are on seperate rows.

Anyone has a clue to select the location where the location_id has both filter_keys?

Upvotes: 1

Views: 63

Answers (2)

Zaynul Abadin Tuhin
Zaynul Abadin Tuhin

Reputation: 32003

you can try like below by using in and condition aggregation

    SELECT l.location_id 
    FROM object_types ot
    LEFT JOIN object_group_types ogt ON ogt.object_type_id = ot.object_type_id
    LEFT JOIN object_groups og ON og.object_group_type_id = ogt.object_group_type_id
    LEFT JOIN object_groups2filters og2f ON og2f.object_group_id = og.object_group_id
    LEFT JOIN filters f ON f.filter_id = og2f.filter_id
    LEFT JOIN locations l ON l.location_id = og.location_id
    WHERE ot.object_type_key = 'TYPE_TENNIS'
   and f.filter_key in ('FILTER_PARKING','FILTER_GRAS')
    GROUP BY l.location_id 
    HAVING SUM(case when f.filter_key = 'FILTER_PARKING' then 1 else 0 end)>=1 AND 
           SUM(case whenf.filter_key = 'FILTER_GRAS' then 1 else 0 end)>=1

Upvotes: 0

Madhur Bhaiya
Madhur Bhaiya

Reputation: 28834

You need to use Group By with Having to filter out the locations.

Try:

SELECT l.location_id 
FROM object_types ot
LEFT JOIN object_group_types ogt ON ogt.object_type_id = ot.object_type_id
LEFT JOIN object_groups og ON og.object_group_type_id = ogt.object_group_type_id
LEFT JOIN object_groups2filters og2f ON og2f.object_group_id = og.object_group_id
LEFT JOIN filters f ON f.filter_id = og2f.filter_id
LEFT JOIN locations l ON l.location_id = og.location_id
WHERE ot.object_type_key = 'TYPE_TENNIS'
GROUP BY l.location_id 
HAVING SUM(f.filter_key = 'FILTER_PARKING') AND 
       SUM(f.filter_key = 'FILTER_GRASS')

Upvotes: 2

Related Questions