MySQL: Wstaw rekord jeśli nie istnieje w tabeli [duplikat]

to pytanie ma już odpowiedzi tutaj : Jak wstawić jeśli nie istnieje w MySQL? (10 odpowiedzi) Zamknięte 2 miesiące temu .

Próbuję wykonać następujące zapytanie:

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

Ale to zwraca błąd. Zasadniczo nie chcę wstawiać rekordu, jeśli pole "nazwa" rekordu już istnieje w innym rekordzie - jak sprawdzić, czy nowa nazwa jest unikalna?

 404
Author: Piskvor left the building, 2010-07-02

16 answers

Nie sugeruję, żebyś to zrobił, ponieważ indeks UNIQUE sugerowany przezPiskvor i inni jest o wiele lepszym sposobem, ale możesz zrobić to, co próbowałeś:

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;

Wstaw rekord:

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  |
+----+--------+-----------+------+

Spróbuj ponownie wstawić ten sam rekord:

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  |
+----+--------+-----------+------+

Wstaw inny rekord:

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  |
+----+--------+-----------+------+

I tak dalej...


Aktualizacja:

Aby zapobiec błędowi #1060 - Duplicate column name W przypadku, gdy dwie wartości mogą być równe, musisz nazwać kolumny wewnętrznej Wybierz:

INSERT INTO table_listnames (name, address, tele)
SELECT * FROM (SELECT 'Unknown' AS name, 'Unknown' AS address, '022' AS tele) 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  |
|  2 | John    | Doe       | 022  |
|  3 | Unknown | Unknown   | 022  |
+----+---------+-----------+------+
 527
Author: Mike,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2021-01-02 20:25:03

INSERT nie pozwala WHERE w składni .

Co możesz zrobić: utwórz UNIQUE INDEX na polu, które powinno być unikalne (name), Następnie użyj:

  • normal INSERT (i obsÅ‚użyć bÅ‚Ä…d, jeÅ›li nazwa już istnieje)
  • JeÅ›li nazwa już istnieje, może to spowodować bÅ‚Ä…d (zamiast bÅ‚Ä™du).]}
  • INSERT ... ON DUPLICATE KEY UPDATE (który wykona UPDATE na koÅ„cu, jeÅ›li nazwa już istnieje, patrz dokumentacja )
 298
Author: Piskvor left the building,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-02 10:40:17


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');
 64
Author: Mahbub Tito,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-08 07:47:07

MySQL dostarcza bardzo Å‚adnego rozwiÄ…zania:

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

Bardzo łatwy w użyciu, ponieważ zadeklarowałeś unikalny klucz podstawowy (tutaj z wartością 5).

 31
Author: sdesvergez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-15 10:42:36
INSERT IGNORE INTO `mytable`
SET `field0` = '2',
`field1` = 12345,
`field2` = 12678;

Tutaj zapytanie mysql, które wstawia rekordy, jeśli nie istnieją i zignoruje istniejące podobne rekordy.

----Untested----
 26
Author: Montaser El-sawy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-06 01:39:07

Możesz łatwo użyć następującego sposobu:

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

W ten sposób możesz wstawić dowolny Nowy raw i jeśli masz duplikaty danych, zastąp konkretną kolumnę (najlepsze kolumny to znaczniki czasu ).
Na przykład:

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';
 20
Author: Arash Hatami,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-13 13:05:59

Aby rozwiązać podobny problem, zmodyfikowałem tabelę, aby miała unikalną kolumnę. Używając Twojego przykładu, przy tworzeniu miałbym coś w stylu:

name VARCHAR(20),
UNIQUE (name)

A następnie użyj następującego zapytania podczas wstawiania do niego:

INSERT IGNORE INTO train
set table_listnames='Rupert'
 14
Author: obsessiveCookie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-03 14:33:41

Jeśli naprawdę nie możesz uzyskać unikalnego indeksu na stole, możesz spróbować...

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;
 13
Author: Brian Hooper,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-02 10:01:18

To zapytanie działa dobrze:

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

I możesz utworzyć tabelę używając następującego zapytania:

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 ;

Uwaga: Utwórz tabelę przy użyciu drugiego zapytania przed próbą użycia pierwszego zapytania.

 11
Author: dakab,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-02 08:18:33

Brian Hooper : Prawie trafiłeś w sedno, ale masz błąd w swoim synatx. Twoja wkładka nigdy nie zadziała. Testowałem w bazie danych i tu jest prawidłowa odpowiedź:

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'

Daję ci mój przykład tabeli Y. Insert jest prawie taki sam jak napisał Bian Hooper, z tym, że umieściłem select FROM DUAL ont z innej tabeli. Cindy, Ivan

 4
Author: Ivan Laharnar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-20 08:55:14
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 )
 4
Author: Oms G,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-02 05:00:48

Wstawiasz nie aktualizujesz wyniku. Możesz zdefiniować kolumnę z nazwą w kolumnie głównej lub ustawić ją jako unikalną.

 3
Author: User 1034,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-02 09:28:22

Miałem problem, a metoda, którą zalecał Mike, zadziałała częściowo, miałem błąd Dublicate Column name = '0' i zmieniłem składnię twojego zapytania jako Ta '

     $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;";

Problem polegał na nazwach kolumn. sum3 był równy sum4 i mysql rzucił dublicate nazwy kolumn, a ja napisałem kod w tej składni i działało idealnie,

 3
Author: Hovhannes Babayan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-15 15:00:01

Miałem podobny problem i musiałem wstawić wiele, jeśli nie istnieje. Z powyższych przykładów doszedłem więc do tej kombinacji... jest tutaj na wypadek, gdyby ktoś go potrzebował.

Zawiadomienie: Musiałem zdefiniować nazwę wszędzie, ponieważ MSSQL tego wymagało... MySQL działa również z*.

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: UTWÓRZ TABELĘ names ( OID int (11) NOT NULL AUTO_INCREMENT, name varchar(32) COLATE utf8_unicode_ci NOT NULL, KLUCZ PODSTAWOWY (OID), UNIKALNY KLUCZ name_UNIQUE (name) ) ENGINE=InnoDB AUTO_INCREMENT=1;

Lub

MSSQL: Utwórz tabelę [nazwy] ( [OID] INT IDENTITY (1, 1) NOT NULL, [nazwa] NVARCHAR (32) NOT NULL, PRIMARY KEY CLUSTERED ([OID] ASC) ); Tworzenie unikalnego indeksu niezakłóconego [Index_Names_Name] na [names] ([name] ASC);

 3
Author: Waldemar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-08 18:49:37

To zapytanie może być użyte w kodzie PHP.

Mam kolumnę ID w tej tabeli, więc muszę sprawdzić duplikację dla wszystkich kolumn z wyjątkiem tej kolumny 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;

I teraz nowa pozycja zostanie dodana tylko w przypadku, gdy nie istnieje wiersz z wartościami ustawionymi w SET string

 2
Author: Andrew,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-20 05:05:09

To nie jest odpowiedź, to tylko notatka. Zapytanie takie jak to w zaakceptowanej odpowiedzi nie działa, jeśli wstawione wartości są duplikatami, jak tutaj:

INSERT INTO `addr` (`email`, `name`) 
  SELECT * FROM (SELECT '[email protected]', '[email protected]') AS tmp 
  WHERE NOT EXISTS (
    SELECT `email` FROM `addr` WHERE `email` LIKE '[email protected]'
  );

Error
SQL query: Copy Documentation

MySQL said: Documentation

#1060 - Duplicate column name '[email protected]'

Przeciwnie, zapytanie podobne do tego z odpowiedzi Mahbuba Titodziała dobrze:

INSERT INTO `addr` (`email`, `name`) 
  SELECT '[email protected]', '[email protected]' 
  WHERE NOT EXISTS (
    SELECT `email` FROM `addr` WHERE `email` LIKE '[email protected]'
  );

1 row inserted.

Testowane w MariaDB

 1
Author: quicktrick,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-09-04 14:04:36