MySQL:如果表中不存在则插入记录

时间:2010-07-02 09:23:30

标签: mysql

我正在尝试执行以下查询:

INSERT INTO table_listnames (name, address, tele)
VALUES ('Rupert', 'Somewhere', '022')
WHERE NOT EXISTS (
    SELECT name FROM table_listnames WHERE name='value'
);

但这会返回错误。基本上我不想插入记录,如果记录的“名称”字段已存在于另一条记录中 - 如何检查新名称是否唯一?

16 个答案:

答案 0 :(得分:426)

我实际上并没有建议你这样做,因为Piskvor和其他人建议的UNIQUE索引是一个更好的方法,但你实际上可以做你正在尝试的事情:

CREATE TABLE `table_listnames` (
  `id` int(11) NOT NULL auto_increment,
  `name` varchar(255) NOT NULL,
  `address` varchar(255) NOT NULL,
  `tele` varchar(255) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB;

插入记录:

INSERT INTO table_listnames (name, address, tele)
SELECT * FROM (SELECT 'Rupert', 'Somewhere', '022') AS tmp
WHERE NOT EXISTS (
    SELECT name FROM table_listnames WHERE name = 'Rupert'
) LIMIT 1;

Query OK, 1 row affected (0.00 sec)
Records: 1  Duplicates: 0  Warnings: 0

SELECT * FROM `table_listnames`;

+----+--------+-----------+------+
| id | name   | address   | tele |
+----+--------+-----------+------+
|  1 | Rupert | Somewhere | 022  |
+----+--------+-----------+------+

尝试再次插入相同的记录:

INSERT INTO table_listnames (name, address, tele)
SELECT * FROM (SELECT 'Rupert', 'Somewhere', '022') AS tmp
WHERE NOT EXISTS (
    SELECT name FROM table_listnames WHERE name = 'Rupert'
) LIMIT 1;

Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0

+----+--------+-----------+------+
| id | name   | address   | tele |
+----+--------+-----------+------+
|  1 | Rupert | Somewhere | 022  |
+----+--------+-----------+------+

插入不同的记录:

INSERT INTO table_listnames (name, address, tele)
SELECT * FROM (SELECT 'John', 'Doe', '022') AS tmp
WHERE NOT EXISTS (
    SELECT name FROM table_listnames WHERE name = 'John'
) LIMIT 1;

Query OK, 1 row affected (0.00 sec)
Records: 1  Duplicates: 0  Warnings: 0

SELECT * FROM `table_listnames`;

+----+--------+-----------+------+
| id | name   | address   | tele |
+----+--------+-----------+------+
|  1 | Rupert | Somewhere | 022  |
|  2 | John   | Doe       | 022  |
+----+--------+-----------+------+

等等......

答案 1 :(得分:270)

INSERT doesn't allow WHERE in the syntax

您可以做什么:在字段上创建UNIQUE INDEX,该name应该是唯一的(INSERT),然后使用:

  • 普通INSERT IGNORE(如果名称已存在,则处理错误)
  • INSERT ... ON DUPLICATE KEY UPDATE(如果名称已存在,无声地失败会导致警告(而不是错误))
  • UPDATE(如果名称已存在,则会在最后执行{{1}},see documentation

答案 2 :(得分:51)

工作:

INSERT INTO users (full_name, login, password) 
  SELECT 'Mahbub Tito','tito',SHA1('12345') FROM DUAL
WHERE NOT EXISTS 
  (SELECT login FROM users WHERE login='tito');

答案 3 :(得分:26)

MySQL提供了一个非常可爱的解决方案:

REPLACE INTO `table` VALUES (5, 'John', 'Doe', SHA1('password'));

非常容易使用,因为您声明了一个唯一的主键(此处值为5)。

答案 4 :(得分:18)

INSERT IGNORE INTO `mytable`
SET `field0` = '2',
`field1` = 12345,
`field2` = 12678;

这里是mysql查询,如果不存在则插入记录,并忽略现有的类似记录。

----Untested----

答案 5 :(得分:16)

您可以轻松使用以下方式:

INSERT INTO ... ON DUPLICATE KEY UPDATE ...

通过这种方式,您可以插入任何 new raw,如果您有重复数据,请替换特定列(最佳列是时间戳)。
例如:

CREATE TABLE IF NOT EXISTS Devices (
  id         INT(6)       NOT NULL AUTO_INCREMENT,
  unique_id  VARCHAR(100) NOT NULL PRIMARY KEY,
  created_at VARCHAR(100) NOT NULL,
  UNIQUE KEY unique_id (unique_id),
  UNIQUE KEY id (id)
)
  CHARACTER SET utf8
  COLLATE utf8_unicode_ci;

INSERT INTO Devices(unique_id, time) 
VALUES('$device_id', '$current_time') 
ON DUPLICATE KEY UPDATE time = '$current_time';

答案 6 :(得分:12)

如果您真的无法在桌面上获得唯一索引,可以尝试...

INSERT INTO table_listnames (name, address, tele)
    SELECT 'Rupert', 'Somewhere', '022'
        FROM some_other_table
        WHERE NOT EXISTS (SELECT name
                              FROM table_listnames
                              WHERE name='Rupert')
        LIMIT 1;

答案 7 :(得分:11)

为了克服类似的问题,我已经使我插入的表具有唯一的列。使用你的例子,在创作时我会有类似的东西:

name VARCHAR(20),
UNIQUE (name)

然后在插入时使用以下查询:

INSERT IGNORE INTO train
set table_listnames='Rupert'

答案 8 :(得分:9)

此查询效果很好:

INSERT INTO `user` ( `username` , `password` )
    SELECT * FROM (SELECT 'ersks', md5( 'Nepal' )) AS tmp
    WHERE NOT EXISTS (SELECT `username` FROM `user` WHERE `username` = 'ersks' 
    AND `password` = md5( 'Nepal' )) LIMIT 1

您可以使用以下查询创建表:

CREATE TABLE IF NOT EXISTS `user` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `username` varchar(30) NOT NULL,
    `password` varchar(32) NOT NULL,
    `status` tinyint(1) DEFAULT '0',
    PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

注意:在尝试使用第一个查询之前,使用第二个查询创建表。

答案 9 :(得分:4)

Brian Hooper: 你几乎达到了目的,但你的synatx有错误。你的插入将永远不会工作。我在我的数据库上测试过,这是正确的答案:

INSERT INTO podatki (datum,ura,meritev1,meritev1_sunki,impulzi1,meritev2,meritev2_sunki,impulzi2)
            SELECT '$datum', '$ura', '$meritve1','$sunki1','$impulzi1','$meritve2','$sunki2','$impulzi2'
                FROM dual
                WHERE NOT EXISTS (SELECT datum,ura
                                      FROM podatki
                                      WHERE datum='$datum' and ura='$ura'

我给你我的y表的例子。插入几乎和Bian Hooper写的一样,只不过我从其他表中选择了FROM FROM DUAL。 问候,伊万

答案 10 :(得分:4)

insert into customer_keyskill(customerID, keySkillID)
select  2,1 from dual
where not exists ( 
    select  customerID  from customer_keyskill 
    where customerID = 2 
    and keySkillID = 1 )

答案 11 :(得分:3)

您正在插入而不是更新结果。 您可以在主列中定义名称列,也可以将其设置为唯一。

答案 12 :(得分:3)

我遇到了问题,Mike建议的方法部分工作,我有一个错误Dublicate Column name ='0',并将查询的语法更改为``

     $tQ = "INSERT  INTO names (name_id, surname_id, sum, sum2, sum3,sum4,sum5) 
                SELECT '$name', '$surname', '$sum', '$sum2', '$sum3','$sum4','$sum5' 
FROM DUAL
                WHERE NOT EXISTS (
                SELECT sum FROM names WHERE name_id = '$name' 
AND surname_id = '$surname') LIMIT 1;";

问题在于列名。 sum3等于sum4和mysql抛出了dublicate列名,我用这种语法编写代码并且它工作得很好,

答案 13 :(得分:2)

我有类似的问题,如果不存在,我需要插入多个。所以从上面的例子中我得到了这个组合......这是为了以防有人需要它。

注意: 我必须在MSSQL需要的地方定义名称... MySQL也可以使用*。

INSERT INTO names (name)
SELECT name
FROM
(
  SELECT name
  FROM
  (
     SELECT 'Test 4' as name
  ) AS tmp_single
  WHERE NOT EXISTS
  (
     SELECT name FROM names WHERE name = 'Test 4'
  )
  UNION ALL
  SELECT name
  FROM
  (
     SELECT 'Test 5' as name
  ) AS tmp_single
  WHERE NOT EXISTS
  (
     SELECT name FROM names WHERE name = 'Test 5'
  )
) tmp_all;

MySQL的:     CREATE TABLE names(       OID int(11)NOT NULL AUTO_INCREMENT,       name varchar(32)COLLATE utf8_unicode_ci NOT NULL,       PRIMARY KEY(OID),       独特的钥匙name_UNIQUEname)     )ENGINE = InnoDB AUTO_INCREMENT = 1;

MSSQL:     CREATE TABLE [名称](         [OID] INT IDENTITY(1,1)NOT NULL,         [name] NVARCHAR(32)NOT NULL,         主要集群([OID] ASC)     );     CREATE UNIQUE NONCLUSTERED INDEX [Index_Names_Name] ON [name]([name] ASC);

答案 14 :(得分:1)

此查询可用于PHP代码。

我在此表中有一个ID列,因此我需要检查除此ID列之外的所有列的重复:

#need to change values
SET @goodsType = 1, @sybType=5, @deviceId = asdf12345SDFasdf2345;    


INSERT INTO `devices` (`goodsTypeId`, `goodsId`, `deviceId`) #need to change tablename and columnsnames
SELECT * FROM (SELECT @goodsType, @sybType, @deviceId) AS tmp
WHERE NOT EXISTS (
    SELECT 'goodsTypeId' FROM `devices` #need to change tablename and columns names
    WHERE `goodsTypeId` = @goodsType
        AND `goodsId` = @sybType
        AND `deviceId` = @deviceId
) LIMIT 1;

现在只有在SET字符串

中配置值不存在的情况下才会添加新项目

答案 15 :(得分:0)

这不是一个答案,只是一个注释。如果插入的值是重复的,则类似accepted answer中的查询的查询将无法正常工作,例如:

INSERT INTO `addr` (`email`, `name`) 
  SELECT * FROM (SELECT 'user@domain.tld', 'user@domain.tld') AS tmp 
  WHERE NOT EXISTS (
    SELECT `email` FROM `addr` WHERE `email` LIKE 'user@domain.tld'
  );

Error
SQL query: Copy Documentation

MySQL said: Documentation

#1060 - Duplicate column name 'user@domain.tld'

相反,像Mahbub Tito's answer中的查询一样工作正常:

INSERT INTO `addr` (`email`, `name`) 
  SELECT 'user@domain.tld', 'user@domain.tld' 
  WHERE NOT EXISTS (
    SELECT `email` FROM `addr` WHERE `email` LIKE 'user@domain.tld'
  );

1 row inserted.

在MariaDB中测试