Domanda

I'm creating a simple bookmark-management webapp in Python(Flask) but mainly to get experience in SQL (using sqlite) though. I am using tags which we can link to the bookmarks in many-to-many fashion(similar to stackoverflow questions). I have created 3 tables as below :

bookmarks :
bm_id | bm_title  | bm_link
1     | bm_title1 | bm_link1
2     | bm_title2 | bm_link2
3     | bm_title3 | bm_link3
4     | bm_title4 | bm_link4

tags :
bm_id | t_name  
1     | t_name1
2     | t_name2
3     | t_name3
4     | t_name4

bookmarktag :
bmt_id | bookmark_id | tag_id
3      |     3       |   3
5      |     3       |   2
6      |     4       |   3
7      |     4       |   2
1      |     1       |   1
2      |     1       |   2
4      |     3       |   1
8      |     2       |   3

I know how to list all the bookmarks associated with a particular tag.

But I want to know how to list bookmarks common to 2 particular tags. For example, if I were to search for bookmarks common to tag 2 & 3; it should show only bookmarks 3 & 4.

I've only been able to list all the bookmarks associated with tags 2 & 3 using SELECT * FROM bookmarktag bmt WHERE bmt.tag_id=2 OR bmt.tag_id=3;. But as you may know it lists all the bookmarks linked to tags 2 & 3.

Thank you!

È stato utile?

Soluzione

Many set operations can be done with compound queries:

SELECT *
FROM bookmarks
WHERE bm_id IN (SELECT bookmark_id FROM bookmarktag WHERE tag_id = 2
                INTERSECT
                SELECT bookmark_id FROM bookmarktag WHERE tag_id = 3)

Altri suggerimenti

This is an example of a "set-within-sets" query. I like to solve these using group by and having:

select bookmark_id
from bookmarktag bmt
group by bookmark_id
having sum(tag_id = 2) > 0 and
       sum(tag_id = 3) > 0;

Each condition in the having clause is looking for one of the tags that you specify. Each requires that the tag appear at least one time.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top