Esto debería proporcionarle lo que necesita... Cada una de las condiciones de la cláusula "OR"d where, puede seguir agregando como un elemento calificado. Luego, simplemente ajuste la cláusula "Tener" para cumplir con el mismo número que los criterios que está permitiendo... Puse la tabla de relaciones primero, ya que tendría un conjunto coincidente más pequeño en el "Valor" de Ciudad o valores de tipo. Asegúrese de tener un índice en la tabla de relaciones en la columna "VALOR".
SELECT STRAIGHT_JOIN
rel.id_obj
from
relations rel
join attributes atr
on rel.id_addr = atr.id
where
( rel.value = 'Apartment' AND atr.name = 'Type' )
or ( rel.value = 'Some City' AND atr.name = 'City' )
group by
atr.id_obj
having
count(*) = 2
limit
0, 20
Si desea todos los datos de objetos reales DE estos resultados, los envolvería en algo como...
select obj.*
from
( complete SQL statement above ) PreQuery
join Object obj on PreQuery.id_obj = obj.id