2013-06-26 103 views
0

我试图从同一个表中选择项目,重新组织数据,然后插入数据到新记录相同的表(基本上我正在采取“ A“记录DNS并将其转换为”PTR“记录)。MySQL:插入选择从一些独特的值

问题是,如果三列存在,我不想创建记录 - 所以基本上,如果三列全都存在(并且它们都必须存在,因为如果只有一列不匹配,那么它应该被插入到数据库中)然后我想让MySQL不要插入它。

这里的表:

mysql> describe records; 
+-------------+----------------+------+-----+---------+----------------+ 
| Field  | Type   | Null | Key | Default | Extra   | 
+-------------+----------------+------+-----+---------+----------------+ 
| id   | int(11)  | NO | PRI | NULL | auto_increment | 
| domain_id | int(11)  | YES | MUL | NULL |    | 
| name  | varchar(255) | YES | MUL | NULL |    | 
| type  | varchar(10) | YES |  | NULL |    | 
| content  | varchar(64000) | YES |  | NULL |    | 
| ttl   | int(11)  | YES |  | NULL |    | 
| prio  | int(11)  | YES |  | NULL |    | 
| change_date | int(11)  | YES |  | NULL |    | 
+-------------+----------------+------+-----+---------+----------------+ 
8 rows in set (0.00 sec) 

下面的SQL我能得到工作,它的工作原理,只是没有其他三个领域是“独一无二”的检查:

INSERT INTO records (domain_id,name,type,content,ttl,prio,change_date) SELECT domain_id AS domain_id, substring_index(content, '.', -1) AS name, 'PTR' AS type, concat(`name`, '.') AS content, ttl AS ttl, prio AS prio, unix_timestamp() AS change_date from records where type='A' 

基本上这里唯一缺少的是,如果domain_id,name和content ALL存在于另一行(基于当前插入),那么我希望它跳过该单个插入并继续下一个插入,因为我不想要相同的记录在数据库中。

回答

0

只需在where子句中添加条件就不存在这样的行。例如:

INSERT INTO records (domain_id,name,type,content,ttl,prio,change_date) SELECT domain_id AS domain_id, substring_index(content, '.', -1) AS name, 
'PTR' AS type, concat(`name`, '.') AS content, ttl AS ttl, prio AS prio, unix_timestamp() AS change_date from records a where type='A' 
and not exists (select * from records b where a.domain_id = b.domain_id and a.name = b.name and a.content = b.content) 
+0

不幸的是,这也行不通。 – drewrockshard

0

做一个LEFT JOIN对基于要检查(假定你只对类型PTR的现有油田感兴趣),只选择记录的3个字段的表不匹配: -

INSERT INTO records (domain_id,name,type,content,ttl,prio,change_date) 
SELECT a.domain_id AS domain_id, 
    substring_index(a.content, '.', -1) AS name, 
    'PTR' AS type, 
    concat(a.`name`, '.') AS content, 
    a.ttl AS ttl, 
    a.prio AS prio, 
    unix_timestamp() AS change_date 
FROM records a 
LEFT OUTER JOIN records b 
ON a.domain_id = b.domain_id 
AND a.name = b.name 
AND a.content = b.content 
AND b.type = 'PTR' 
WHERE b.id IS NULL 
AND a.type = 'A' 
+0

这不起作用 - 它将数据库中的所有内容都包含进去,然后在存在的情况下创建它。 – drewrockshard

+0

它不应该这样做。它从记录中选择a作为获取所有现有的A型记录,并将其与记录作为b连接,并用LEFT JOIN在b记录中检查PTR的类型。任何发现b记录的地方都会被忽略 – Kickstart

+0

Kickstart:我有40行数据,每次运行这条语句,它都会增加40条数据 - 所以它没有做正确的事情。 – drewrockshard