Sql 从与另一个表具有相同关系的表中获取字段
我会尽力解释我的案子。 我正在制作一个网站,在那里你可以通过浏览他们的标签找到主题。没什么奇怪的。不过,我在一些问题上遇到了棘手的问题。他们可能对你来说很容易,我做了很多工作,脑子里乱七八糟 我有表格主题和标签。它们使用包含topic_id和tag_id的表tags_topics进行连接。当用户想要查找主题时,他们可能首先选择一个要筛选的标记,然后将另一个标记添加到筛选器中。然后,我进行一个查询,以获取包含两个选定标记的所有主题。它们也可能有其他标记,但必须选择这些标记进行筛选。要过滤的标签数量不同,但我们总是有一个用户选择的标签列表来过滤。 这主要是在中得到了回答,我选择了多重连接解决方案 现在我需要获取用户可以过滤的标记。因此,如果我们已经定义了一个包含2个标记的过滤器,那么我需要获取所有标记,但过滤器中与包含过滤器中所有标记的主题相关联的标记除外。这听起来可能很奇怪,所以我将给出一个实际的例子:P 假设我们有三个主题:网球、体操和高尔夫 网球有标签:运动、球、球场和球拍 健身房有标签:运动、训练和肌肉 高尔夫有标签:运动、球、棍棒和户外 用户选择tag sport,所以我们会显示所有三个网球、健身房和高尔夫,并显示球、球场、球拍、训练、肌肉、棍棒和其他可能的过滤器。 用户现在将球添加到过滤器中。过滤器现在是运动和球,所以我们展示的主题是网球和高尔夫,以及球场、球拍、棍子和室外可能的过滤器。 用户现在将球场添加到过滤器中,因此我们显示网球和球拍作为附加的可能过滤器。 我希望我说得有道理。顺便说一下,我正在使用MySQLSql 从与另一个表具有相同关系的表中获取字段,sql,mysql,join,filter,tags,Sql,Mysql,Join,Filter,Tags,我会尽力解释我的案子。 我正在制作一个网站,在那里你可以通过浏览他们的标签找到主题。没什么奇怪的。不过,我在一些问题上遇到了棘手的问题。他们可能对你来说很容易,我做了很多工作,脑子里乱七八糟 我有表格主题和标签。它们使用包含topic_id和tag_id的表tags_topics进行连接。当用户想要查找主题时,他们可能首先选择一个要筛选的标记,然后将另一个标记添加到筛选器中。然后,我进行一个查询,以获取包含两个选定标记的所有主题。它们也可能有其他标记,但必须选择这些标记进行筛选。要过滤的标签数量
SELECT topic_id
FROM topic_tag
WHERE tag_id = 1
OR tag_id = 2
OR tag_id = 3
GROUP BY topic_id
HAVING COUNT(topic_id) = 3;
上面的查询将获得三个标记ID均为1、2和3的所有主题ID。然后将其用作子查询:
SELECT tag_name
FROM tag
INNER JOIN topic_tag
ON tag.tag_id = topic_tag.tag_id
WHERE topic_id IN
( SELECT topic_id
FROM topic_tag
WHERE tag_id = 1
OR tag_id = 2
OR tag_id = 3
GROUP BY topic_id
HAVING COUNT(topic_id) = 3
)
AND
(
tag.tag_id <> 1
OR tag.tag_id <> 2
OR tag.tag_id <> 3
)
我想这就是你要找的
SELECT DISTINCT `tags`.`tag`
FROM `tags`
LEFT JOIN `tags_topics` ON `tags`.`id` = `tags_topics`.`tag_id`
LEFT JOIN `topics` ON `tags_topics`.`topic_id` = `topics`.`id`
LEFT JOIN `tags_topics` AS `tt1` ON `tt1`.`topic_id` = `topics`.`id`
LEFT JOIN `tags` AS `t1` ON `t1`.`id` = `tt1`.`tag_id`
LEFT JOIN `tags_topics` AS `tt2` ON `tt2`.`topic_id` = `topics`.`id`
LEFT JOIN `tags` AS `t2` ON `t2`.`id` = `tt2`.`tag_id`
LEFT JOIN `tags_topics` AS `tt3` ON `tt3`.`topic_id` = `topics`.`id`
LEFT JOIN `tags` AS `t3` ON `t3`.`id` = `tt3`.`tag_id`
WHERE `t1`.`tag` = 'tag1'
AND `t2`.`tag` = 'tag2'
AND `t3`.`tag` = 'tag3'
AND `tags`.`tag` NOT IN ('tag1', 'tag2', 'tag3')
应该为您提供一个主题列表,其中包含所选主题的所有标签。通用解决方案位于我的头顶,但容易出现拼写错误:
CREATE VIEW shared_tags_count AS
SELECT topic_to_tag1.topic_id AS topic_id1, topic_to_tag2.topic_id AS topic_id2, COUNT(*) as number
FROM topic_to_tag as topic_to_tag1
JOIN topic_to_tag as topic_to_tag2
ON topic_to_tag1.topic_id <> topic_to_tag2.topic_id
AND topic_to_tag1.tag_id = topic_to_tag2.tag_id
GROUP BY topic_to_tag1.topic_id, topic_to_tag2.topic_id;
CREATE VIEW tags_count AS
SELECT topic_id, COUNT(*) as number
FROM topic_to_tag
GROUP BY topic_id
CREATE VIEW related_topics AS
SELECT shared_tags_count.topic_id1, shared_tags_count.topic_id2
FROM shared_tags_count
JOIN tags_count
ON topic_id=topic_id1
AND shared_tags_counts.number = tags_count.number
CREATE VIEW related_tags AS
SELECT related_topics.topic_id1 as topic_id, topic_to_tag.tag_id
FROM related_topics
JOIN topic_to_tag
ON raleted_topics.tag_id2 = topic_to_tag.topic_id
您只需查询相关的标签视图
有趣的挑战顺便说一句。不清楚是什么让标记1、2和3在某种程度上与众不同,而“一堆其他标记”却没有。为什么它们是必需的,而其余的则不是,我们怎么知道这一点?这是我们可以假设的预定义标记列表吗?您可能希望给出一些表结构并更好地解释这个问题。我想我得到了你想要的,但我花了5次时间才明白。我看到了@achinda99 Ye的精确副本,我会努力把我的问题写得更好@比尔·卡温并不是真的,这次正好相反:P我想你们认为这是重复的,因为我解释得很糟糕。我将试着写一个更好的问题@混乱我将在我的问题中描述使用场景。不用in,你可以做一个内部连接,但是你必须重命名某些列,我感觉很懒。谢谢,这看起来是一个简单的解决方案。与执行子查询相比,在性能方面感觉更好。是的,但它仅限于3个标记。但查询可以在应用程序代码中动态生成,主要是因为表名;我喜欢把问题分解成观点。更多的代码,但当您的模式发生更改时,更容易维护。是的,我可以看到:实际上我从未使用过视图,我可能需要看一看。
CREATE VIEW shared_tags_count AS
SELECT topic_to_tag1.topic_id AS topic_id1, topic_to_tag2.topic_id AS topic_id2, COUNT(*) as number
FROM topic_to_tag as topic_to_tag1
JOIN topic_to_tag as topic_to_tag2
ON topic_to_tag1.topic_id <> topic_to_tag2.topic_id
AND topic_to_tag1.tag_id = topic_to_tag2.tag_id
GROUP BY topic_to_tag1.topic_id, topic_to_tag2.topic_id;
CREATE VIEW tags_count AS
SELECT topic_id, COUNT(*) as number
FROM topic_to_tag
GROUP BY topic_id
CREATE VIEW related_topics AS
SELECT shared_tags_count.topic_id1, shared_tags_count.topic_id2
FROM shared_tags_count
JOIN tags_count
ON topic_id=topic_id1
AND shared_tags_counts.number = tags_count.number
CREATE VIEW related_tags AS
SELECT related_topics.topic_id1 as topic_id, topic_to_tag.tag_id
FROM related_topics
JOIN topic_to_tag
ON raleted_topics.tag_id2 = topic_to_tag.topic_id