gpt4 book ai didi

MySQL多对多补集

转载 作者:可可西里 更新时间:2023-11-01 07:33:31 25 4
gpt4 key购买 nike

我一直在网上寻找并向人们寻求指导,但似乎没有人知道问题的正确(相对快速)解决方案:

我有三个表,经典的多对多解决方案:

  • entries: id (int), title (varchar[255]), content (text)
  • 标签:id (int), name (varchar[255]), slug (varchar[255])
  • entries_tags: id(int), entry_id(int), tag_id(int)

到目前为止没有任何异常。现在假设我在标签中有测试数据(我将 slug 排除在外,因为它们并不重要):

ID | name
1. | one
2. | two
3. | three
4. | four
5. | five

我也有三个条目:

ID | title
1. | Something
2. | Blah blah blah
3. | Yay!

和关系:

ID | entry_id | tag_id
1. | 1 | 1
2. | 1 | 2
3. | 2 | 1
4. | 2 | 3
5. | 3 | 1
6. | 3 | 2
7. | 3 | 3
8. | 4 | 1
9. | 4 | 4

好的,我们有我们的测试数据。我想知道如何获取所有具有标签一但没有标签三(即条目 1 和 4)的条目。

我知道如何用子查询来做,问题是,它需要很多时间(10 万个条目大约需要 10-15 秒)。有什么办法可以用 JOIN 做到这一点吗?还是我遗漏了什么?

编辑 我想我应该提到我需要一个适用于数据集而不是单个标签的解决方案,所以将我问题中的“一”替换为“一”、“二”和“二”与“三”、“四”

edit2 提供的答案是正确的,但是太慢了,无法实际使用。我想让它工作的唯一方法是使用第 3 方搜索引擎,如 Lucene 或 ElasticSearch。

最佳答案

以下脚本选择具有标签 OneTwo 而没有标签 ThreeFour 的条目:

SELECT DISTINCT
et.entry_id
FROM entries_tags et
INNER JOIN tags t1 ON et.tag_id = t1.id AND t1.name IN ('One', 'Two')
LEFT JOIN tags t2 ON et.tag_id = t2.id AND t2.name IN ('Three', 'Four')
WHERE t2.id IS NULL

替代解决方案:INNER JOIN 替换为 WHERE EXISTS,这使我们能够摆脱(相当昂贵的)DISTINCT:

SELECT
et.entry_id
FROM entries_tags et
LEFT JOIN tags t2 ON et.tag_id = t2.id AND t2.name IN ('Three', 'Four')
WHERE t2.id IS NULL
AND EXISTS (
SELECT *
FROM tags t1
WHERE t1.id = et.tag_id
AND t1.name IN ('One', 'Two')
)

关于MySQL多对多补集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7632510/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com