2

我们有两个表(comment 和 comment_tags),如下所示:

mysql> describe comment;
+--------------+--------------+------+-----+---------+-------+
| Field        | Type         | Null | Key | Default | Extra |
+--------------+--------------+------+-----+---------+-------+
| id           | int(11)      | YES  |     | NULL    |       |
| blogpost_id  | int(11)      | YES  |     | NULL    |       |
| comment_text | varchar(256) | YES  |     | NULL    |       |
+--------------+--------------+------+-----+---------+-------+

mysql> describe comment_tags;
+------------+-------------+------+-----+---------+-------+
| Field      | Type        | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+-------+
| comment_id | int(11)     | YES  |     | NULL    |       |
| tag        | varchar(80) | YES  |     | NULL    |       |
+------------+-------------+------+-----+---------+-------+

每条评论都可以有不同的标签与之关联。现在我们想将所有评论标签传播到同一篇博文的所有评论。所以本质上我们想让所有的comment_tags对于每篇博文的所有评论都是一样的。

我知道我们可以编写脚本或 PL/SQL 来执行此操作。但我想知道是否有一个 mySQL 查询可以做到这一点。

是否有可能有一个 mySQL 查询将评论上的所有标签传播到同一博客文章的所有评论?

4

1 回答 1

2

假设您在表上有一个primary key包含您的comment_idtag字段的组合comment_tags(听起来应该如此),那么您可以使用insert ignore

insert ignore into comment_tags
select distinct c.id, ct.tag
from comment c 
  join comment c2 on c.blogpost_id = c2.blogpost_id
  join comment_tags ct on ct.comment_id in (c.id, c2.id)

编辑

鉴于您的评论,您可以not exists在查询中包括:

insert into comment_tags
select distinct c.id, ct.tag
from comment c 
  join comment c2 on c.blogpost_id = c2.blogpost_id
  join comment_tags ct on ct.comment_id in (c.id, c2.id)
where not exists (
  select 1 
  from comment_tags ct2
  where c.id = ct2.comment_id and ct.tag = ct2.tag);

最后评论 - 出于性能原因,您最好使用left join/nullvs not exists。这似乎在不同的 RDBMS 之间有所不同:

insert into comment_tags
select distinct c.id, ct.tag
from comment c 
  join comment c2 on c.blogpost_id = c2.blogpost_id
  join comment_tags ct on ct.comment_id in (c.id, c2.id)
  left join comment_tags ct2 on c.id = ct2.comment_id and ct.tag = ct2.tag
where ct2.comment_id is null;
于 2013-10-08T00:21:08.477 回答