Search code examples
mysqlgroup-concat

SELECT WHERE (1 AND 2) IN GROUP_CONCAT()


entity
---
id  name
---
1   one
2   two
3   three

property
---
id  name
---
1   prop1
2   prop2
3   prop3

entity_property
---
entity_id   property_id
---
1           1
1           2
1           3
2           1

I wanna get entities that have at least 1 and 2 (but can have even more) properties.

This is a workaround I don't like:

SELECT entity_property.entity_id,
(GROUP_CONCAT(entity_property.property_id)) as props
FROM `entity_property` 
JOIN entity
ON entity_property.entity_id = entity.id
GROUP BY entity.id

It returns:

entity_id props
---
1   1,2,3
2   1

Then I have to explode it with server language and then exclude.


This query returns all entity's rows:

SELECT entity.id
FROM entity
WHERE (1 AND 2) IN
    (SELECT property_id
     FROM entity_property
     LEFT JOIN entity 
     ON entity_property.entity_id = entity.id
     WHERE entity_property.entity_id = entity.id)

This query causes error:

SELECT entity.id as ent_id
FROM entity
WHERE (1 AND 2) IN
    (SELECT property_id
     FROM entity_property
     LEFT JOIN entity 
     ON entity_property.entity_id = entity.id
     WHERE entity_property.entity_id = ent_id)

Solution

  • You can get the entity ids using group by and having:

    SELECT ep.entity_id
    FROM `entity_property` ep
    WHERE ep.property_id IN (1, 2)
    GROUP BY ep.entity_id
    HAVING COUNT(DISTINCT ep.property_id) = 2;
    

    Notes:

    • This does not require the entity table.
    • The DISTINCT is not necessary if duplicate pairs are not allowed in entity_property.
    • For more properties, you need to change bother the WHERE and the HAVING (where "2" is the number of things you want to match).