作者热门文章
- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我一直在网上寻找并向人们寻求指导,但似乎没有人知道问题的正确(相对快速)解决方案:
我有三个表,经典的多对多解决方案:
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。
最佳答案
以下脚本选择具有标签 One
和 Two
而没有标签 Three
和 Four
的条目:
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/
补: Rest 风格请求处理的的内容补充(1) Rest风格请求:注意事项和细节 客户端是PostMan 可以直接发送Put,delete等方式请求,可不设置Filter 如果哟啊
我是一名优秀的程序员,十分优秀!