postgresql - Simplify and/or optimize sql query with INTERSECT or HAVING -
i have following data:
tag_id | taggable_id --------+------------- 1 | 1 2 | 1 3 | 1 4 | 1 1 | 2 2 | 2 5 | 2 6 | 2 7 | 3 8 | 3 9 | 3 10 | 3
and want bring taggable_ids in group of tag_ids , in group , another... (max 4 groups).
example:
- if search taggable_ids tag_id 1 or 7 , tag_id 4 should return 1
- if search taggable_ids tag_id 1 , tag_id 6 , tag_id 2 or 8 should return 2
- if search taggable_ids tag_id 8 , tag_id 5 should not return ids
in gross way(for second example), query following:
select taggable_id taggings tag_id in (1) intersect select taggable_id taggings tag_id in (6) intersect select taggable_id taggings tag_id in (2,8)
i think simplifying it, looks like:
select taggable_id taggings tag_id in (1,2,6,8) group taggable_id having count(*)=3
but i'm wondering if can done in simpler way. thoughts?
this can cast case of relational division. have assembled arsenal of query techniques under related question:
depending on data distribution , other factors, may fastest:
select distinct taggable_id taggings t1 join taggings t2 using (taggable_id) join taggings t3 using (taggable_id) t1.tag_id = 1 , t2.tag_id = 6 , t3.tag_id in (2, 8);
assuming unique (tag_id, taggable_id)
, distinct
not needed example. might necessary other (list) predicates.
sql fiddle (building on @clodoaldo's, thanks).
Comments
Post a Comment