我有一个SQLIte数据库,其中包含用于标记的位置和表的表,
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)
)
我还有第三个表来映射前两个之间的关联,
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)
)
我可以使用以下命令
获取哪些地方标记了哪些标签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
将返回这样的内容,
id | name | id | name
---------------------------------
1 | McDonalds | 1 | Burgers
2 | Pizza Hut | 2 | Pizza
3 | Burger King | 1 | Burgers
我想知道是否可以构造一个查询,以便返回共享两个或多个标签的地点的名称。例如,如果McDonalds
和Burger King
共享标记Burgers
和Fries
,那么我想将此列出,
p1id | p1name | p2id | p2name | t1id | t1name | t2id | t2name
--------------------------------------------------------------------------------
1 | McDonalds | 3 | Burger King | 1 | Burgers | 3 | Fries
这可以用SQL吗?
答案 0 :(得分:2)
您可以使用此查询生成以下结果:
select p1.name, p2.name, t.name
from places p1
join placestags pt1 on p1.id=pt1.placeid
join placestags pt2 on pt1.tagid=pt2.tagid and pt2.placeid <> p1.id
join places p2 on pt2.placeid=p2.id
join tags t on t.id=pt1.tagid
order by p1.id, t.id
这并没有像你想要的那样将所有内容整合到一行中(你需要一个支点,而我认为sqlite没有它),但它可以让你看到发生了什么。以下是您从此查询中获得的内容:
Place1 | Place2 | Shared_Tag
------------|----------------|-----------
McDonalds Burger King Burgers
McDonalds Burger King Fries
Burger King McDonalds Burgers
Burger King McDonalds Fries
编辑(回复评论):
如果您希望缩短查询时间,请尝试减少连接数,并删除对称重复项,如下所示:
select pt1.placeid, pt2.placeid, pt1.tagid
from placestags pt1
join placestags pt2 on pt1.tagid=pt2.tagid and pt2.placeid > pt1.placeid
order by pt1.placeid, pt1.tagid
答案 1 :(得分:1)
这并不能解决“查找相关性”问题,但是因为你也有点要求......
sqlite支持交叉,因此您可以执行以下操作。如果我们知道两个标签,我们可以找到我们想要的标签的交叉点。它不漂亮,可能不是长期的东西,但如果你只是试图了解你的数据,它可能会有所帮助。
假设我们有两个id为1&amp;的标签。 2:
SELECT places.name FROM places
INNER JOIN placestags ON places.id=placestags.placeid
WHERE placestags.tagid = 1
INTERSECT
SELECT places.name FROM places
INNER JOIN placestags ON places.id=placestags.placeid
WHERE placestags.tagid = 2;