I have a SQLIte database with tables for places and tables for tags,
CREATE TABLE places (
id INTEGER NOT NULL,
name VARCHAR(256),
address VARCHAR(256),
PRIMARY KEY (id)
)
CREATE TABLE tags (
id INTEGER NOT NULL,
name VARCHAR(256) NOT NULL,
PRIMARY KEY (id)
)
I also have a third table to map the associations between the first two,
CREATE TABLE placestags (
id INTEGER NOT NULL,
placeid INTEGER,
tagid INTEGER,
PRIMARY KEY (id),
FOREIGN KEY(placeid) REFERENCES places (id),
FOREIGN KEY(tagid) REFERENCES tags (id)
)
I can grab which places are tagged with which tags with the following command,
SELECT places.id, places.name, tags.id, tags.name
FROM (placestags INNER JOIN places on placestags.placeid = places.id
INNER JOIN tags on tags.id = placestags.tagid)
WHERE placestags.tagid=tags.id
Which will return something like this,
id | name | id | name
---------------------------------
1 | McDonalds | 1 | Burgers
2 | Pizza Hut | 2 | Pizza
3 | Burger King | 1 | Burgers
I am wondering if it is possible to construct a query such that it returns the names of places which share two or more tags. For example, if McDonalds and Burger King shared both the tags Burgers and Fries, then I’d like to list that out like this,
p1id | p1name | p2id | p2name | t1id | t1name | t2id | t2name
--------------------------------------------------------------------------------
1 | McDonalds | 3 | Burger King | 1 | Burgers | 3 | Fries
Is this possible with SQL?
You can use this query to produce results below:
This does not get everything into a single row like you wanted (you’d need a pivot for that, and I don’t think sqlite has it), but it lets you see what is going on. Here is what you’d get from this query:
EDIT (in response to a comment):
If you are looking to shorten the query time, try reducing the number of joins, and remove the symmetric duplicates, like this: