如果帖子和标签之间存在多对多关系,我该如何选择包含特定标签的帖子?
更新:
我遇到的问题是,由于 where tag.name = 'xxx',只选择了那个标签。我想要的是选择所有指定了标签的帖子,tgt 及其所有标签,例如。
Post 1 -> tag1, tag2
Post 2 -> tag1, tag3
Post 3 -> tag2, tag3
Run Code Online (Sandbox Code Playgroud)
目前我得到的是
Post 1 -> tag2 // missing tag1
Post 3 -> tag2 // missing tag3
Run Code Online (Sandbox Code Playgroud)
cle*_*tus 17
假设这些表:
最后一个表通常称为连接表,促进了帖子和标签之间的多对多关系。
SELECT p.*
FROM posts p
JOIN posttags pt ON p.id = pt.post_id
JOIN tags t ON pt.tag_id = t.id
WHERE t.name = 'sql'
Run Code Online (Sandbox Code Playgroud)
基本上,将多对多关系视为两个一对多关系,因为这就是它们在普通 RDBMS 中的实现方式。所以上面的查询有一个从 Posts 到 PostTags 和另一个从 Tags 到 PostTags 的一对多连接。
我创建的 PostTags 表有一个复合主键,即(post_id, tag_id). 这种组合将是独一无二的。许多人不喜欢复合键,因此您经常会看到人们创建主键列:
两种方法都可以。这主要是哲学上的差异。
更新:如果您想选择所有具有特定标签的帖子以及这些帖子的所有标签,则:
SELECT p.*
FROM posts p
JOIN posttags pt ON p.id = pt.post_id
JOIN tags t ON pt.tag_id = t.id
WHERE p.id IN
(SELECT post_id
FROM PostTags pt
JOIN tags t ON pt.tag_id = t.id
WHERE t.name = 'xyz')
Run Code Online (Sandbox Code Playgroud)
另一种方法是:
SELECT p.*
FROM posts p
JOIN posttags pt ON p.id = pt.post_id
JOIN tags t ON pt.tag_id = t.id
WHERE EXISTS
(SELECT post_id
FROM PostTags pt
JOIN tags t ON pt.tag_id = t.id
WHERE t.name = 'xyz'
AND pt.post_id = p.id)
Run Code Online (Sandbox Code Playgroud)
哪个性能更好需要进行测试,并且可能因数据库供应商和版本而异。一个好的优化器(即 Oracle)可能会优化它们以执行相同的操作。其他人可能不会。
现在这会让你像这样返回行:
Post 1, tag 1
Post 1, tag 2
Post 3, tag 2
Post 3, tag 3
Run Code Online (Sandbox Code Playgroud)
所以你需要将它们组合起来,最好是在应用程序逻辑而不是 SQL 中。某些 RDBMS 具有针对此类事物的特定于供应商的扩展,例如 MySQL 的GROUP_CONCAT()功能。
| 归档时间: |
|
| 查看次数: |
12771 次 |
| 最近记录: |