这是我的问题:
INSERT INTO comments (root_id, r_id, user_id, comment_content)
SELECT DISTINCT root_id, r_id,user_id, comment_content FROM comments_old WHERE 1
注意我在comments(root_id, r_id, user_id)
上有唯一索引,上面的查询失败,因为DISTINCT
关注重复的comment_content
列值,并且它不存在于唯一索引。 (因为其类型为TEXT
,我无法将其添加到唯一索引中)。
无论如何,我想选择comment_content
但不关心是否重复此列。我怎么能这样做?
答案 0 :(得分:1)
在SQL的大多数方言中,没有办法表达“选择一个值,我不关心哪个”。可能有一种mysql方言方式,但我希望标准:
select root_id,r_id,user_id,MAX(comment_content)
from comments_old
group by root_id,r_id,user_id
应该有效。当然,MAX
有点武断,MIN
也可以使用 - 但你说你不在乎选择了什么价值。
答案 1 :(得分:1)
使用包含不同内容的子查询,并将其连接到查询comment_content值的表本身。
INSERT INTO comments (root_id, r_id, user_id, comment_content)
SELECT a.root_id, a.r_id, a.user_id, b.comment_content FROM
(SELECT DISTINCT root_id, r_id,user_id FROM comments_old WHERE 1) a, comments_old b
WHERE a.root_id = b.root_id and a.r_id = b.r_id and a.use_id = b.user_id
如果同一组键存在两个不同的comment_content值,这将为您提供两行。
答案 2 :(得分:1)
您也可以使用略有不同的方法,并对违反唯一密钥做出反应。
你可以,例如使用insert ignore
INSERT IGNORE INTO comments (root_id, r_id, user_id, comment_content)
SELECT DISTINCT root_id, r_id,user_id, comment_content
FROM comments_old WHERE 1;
INSERT INTO comments (root_id, r_id, user_id, comment_content)
SELECT DISTINCT root_id, r_id,user_id, comment_content
FROM comments_old WHERE 1
ON DUPLICATE KEY UPDATE comment_content = values(comment_content);
insert ignore
也会忽略其他类型的错误,而ON DUPLICATE KEY UPDATE
(或ON DUPLICATE KEY IGNORE
)只会跳过(或处理)唯一键错误。如果您使用update
,在这种情况下,它将始终采用最新值(因此将覆盖现有行)。
使用group by
的一个重要区别是,如果带有该键的行已经在表中,这也将忽略一个新行 - 这不是您要求的,但可能是您正在查找的内容对
答案 3 :(得分:1)
由于MySQL的一项功能,以下内容也应该有效*:
INSERT INTO comments (root_id, r_id, user_id, comment_content)
SELECT root_id, r_id, user_id, comment_content
from comments_old
group by root_id, r_id, user_id
这是因为MySQL将允许未分组的,未聚合的值包含在GROUPed选择中 - 所选的值基本上是随机的(在特定分组的值内)。
。* - 在5.7.5之前的MySQL版本中,或者未启用ONLY_FULL_GROUP_BY的版本 - 有关详细信息,请参阅MySQL Documentation。