MySQL: вставить запись, если не существует в таблице - PullRequest
336 голосов
/ 02 июля 2010

Я пытаюсь выполнить следующий запрос:

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

Но это возвращает ошибку.По сути, я не хочу вставлять запись, если поле «имя» записи уже существует в другой записи - как проверить, является ли новое имя уникальным?

Ответы [ 15 ]

438 голосов
/ 02 июля 2010

На самом деле я не предлагаю вам это делать, так как индекс 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  |
+----+--------+-----------+------+

И так далее ...

272 голосов
/ 02 июля 2010

INSERT не допускает WHERE в синтаксисе .

Что вы можете сделать: создайте UNIQUE INDEX в поле, которое должно быть уникальным (name), затем используйте либо:

  • normal INSERT (и обработать ошибку, если имя уже существует)
  • INSERT IGNORE (что произойдет сбой молча вызовет предупреждение (вместо ошибки), если имя уже существует)
  • INSERT ... ON DUPLICATE KEY UPDATE (который будет выполнять UPDATE в конце, если имя уже существует, см. Документацию )
51 голосов
/ 08 мая 2013

Работал:

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');
25 голосов
/ 15 апреля 2015

MySQL предлагает очень симпатичное решение:

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

Очень прост в использовании, поскольку вы объявили уникальный первичный ключ (здесь со значением 5).

19 голосов
/ 06 января 2013
INSERT IGNORE INTO `mytable`
SET `field0` = '2',
`field1` = 12345,
`field2` = 12678;

Здесь запрос mysql, который вставляет записи, если они не существуют, и игнорирует существующие подобные записи.

----Untested----
16 голосов
/ 14 марта 2017

Вы можете легко использовать следующий способ:

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

Таким образом, вы можете вставить любой новый 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';
12 голосов
/ 02 июля 2010

Если вы действительно не можете получить уникальный индекс для таблицы, попробуйте ...

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;
11 голосов
/ 20 февраля 2014

Чтобы преодолеть подобную проблему, я создал таблицу, в которую вставляю уникальный столбец. Используя ваш пример, при создании у меня было бы что-то вроде:

name VARCHAR(20),
UNIQUE (name)

, а затем используйте следующий запрос при вставке в него:

INSERT IGNORE INTO train
set table_listnames='Rupert'
9 голосов
/ 02 февраля 2016

Этот запрос работает хорошо:

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 ;

Примечание. Создайте таблицу, используя второй запрос, прежде чем пытаться использоватьпервый запрос.

4 голосов
/ 02 декабря 2014
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 )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...