Вставлять строки только тогда, когда существует идентификатор из другой таблицы

Моя программа получает список идентификаторов, некоторые из которых находятся в нашей системе, некоторые из которых не являются. Цель состоит в том, чтобы сделать запись в таблицу для идентификаторов, существующих в нашей системе, но игнорировать те, которые этого не делают.

Пример:

Incomming My System Inserted 555 583 583 583 599 

Моя первоначальная мысль заключалась в том, чтобы использовать INSERT IGNORE но список идентификаторов для проверки находится в таблице users, а строки вставляются в таблицу событий. Я также попробовал ограничение внешнего ключа, но INSERT IGNORE не сработает молча с FK – он выдает ошибку, которая убивает любые последующие вставки.

Мой текущий угол атаки состоит в том, чтобы читать во всех идентификаторах таблицы пользователей на PHP и проверять идентификаторы на PHP перед попыткой вставить, но это кажется субоптимальным. Есть ли способ MySQL сделать это?

 INSERT INTO your_id_table (ID) SELECT ID FROM my_system_table WHERE ID IN (list_of_ids) 

Я надеюсь, что это ясно, с этим вам вообще не нужно делать никаких проверок, вы просто запускаете запрос и выполняете его.

Вы можете использовать оператор if (), который проверяет, существует ли значение в таблице пользователя перед вставкой.

 if exists (select * from user where id = @id) begin /*insert*/ end else begin /*return a status message or insert in error table to track failed records*/ end 

Это довольно уродливый способ сделать это, но он работает:

 $ids = array( /* ids */ ); $ids = implode(',', $ids); $sql = 'SELECT `id` FROM `table` WHERE `id` IN ('.$ids.')'; $result = $db -> query($sql); $exists = $result -> fetch_all(); $doesntExist = array_diff($ids, $exists); 

Вы можете попробовать:

 INSERT INTO Inserted(id) VALUES SELECT id FROM Incoming WHERE id IN (SELECT id FROM My_System) 

Это выбирает идентификаторы Incomming, которые также находятся в My_System, и вставляет их в Inserted.

Вы можете сделать что-то вроде этого:

 INSERT INTO events (iduser) SELECT iduser FROM users WHERE iduser IN (1,2,3,4,5) 

Этот запрос будет возвращать только идентификаторы пользователя, которые присутствуют в таблице, поэтому это должно сделать трюк.

Если у вас больше столбцов для вставки, это будет выглядеть примерно так:

 $idsToInsert = "1,2,3,4,5,6"; $query = "INSERT INTO events (iduser, title) SELECT iduser, ".$title." FROM users WHERE iduser IN (".$idsToInsert.")"; 

И не забудьте очистить свой ввод, используя mysql_real_escape, вы также можете использовать параметризованный запрос s для этого.

Эта последняя часть запроса, которую вы должны генерировать динамически через PHP, но это не проблема

Ссылка Mysql для вставки в таблицу select from находится здесь: http://dev.mysql.com/doc/refman/5.0/en/insert-select.html

Вы можете сделать это на PHP Code

 $result = mysql_query("SELECT id FROM another_table WHERE id = '100'"); $number_of_rows = mysql_num_rows($result); if ($number_of_rows > 0) { // ID exist in other table } 

FK производит ошибку, которая убивает любые последующие вставки

Почему это убивает следующие вставки? Вставляйте вставки один за другим, проверяйте ошибки mysql.

Это самое элегантное решение, о котором я могу думать:

 INSERT INTO events (id) SELECT id FROM my_system ms LEFT JOIN incoming i ON i.id = ms.id WHERE i.id IS NOT NULL 

Идея здесь заключается в том, что вы исключаете эти записи в таблице «Входящие», которые не имеют соответствующей записи в таблице my_system, потому что набор результатов будет нулевым для входящих идентификаторов.

Похоже, что некоторые другие люди уже придумали подобное решение! Надеюсь, это поможет, так или иначе.

Внутреннее соединение – самый чистый способ вытащить его

 INSERT INTO events (id) SELECT incoming.id FROM my_system ms INNER JOIN incoming i USING (id); 

Просто загрузите входящие идентификаторы во входящую таблицу. Кроме того, не забудьте указать id как ПЕРВИЧНЫЙ КЛЮЧ для обеих таблиц.

Просто делать:

 insert into events (id, value1, value2, ...) select id, @value1, @value2, ... from users where id = @id 

Таким образом, он будет вставляться только в том случае, если идентификатор уже существует в вашей таблице users . Это предполагает, что значение id уникально для каждой строки в таблице users , но если бы оно не просто добавлялось distinct после выбора, чтобы вставить только одну строку.