MySQL Условная Вставка

У меня проблемы с формированием условной вставки

У меня есть x_table со столбцами (экземпляр, пользователь, элемент), где идентификатор экземпляра уникален. Я хочу вставить новую строку, только если у пользователя уже нет данного элемента.

Например, попытка вставить экземпляр = 919191 пользователь = 123 элемент = 456

Insert into x_table (instance, user, item) values (919191, 123, 456) 
    ONLY IF there are no rows where user=123 and item=456 

Любая помощь или руководство в правильном направлении будет высоко ценится.

82 голоса | спросил The Unknown 27 Mayam09 2009, 07:48:00

12 ответов


0

Если ваша СУБД не накладывает ограничений на то, какую таблицу вы выбираете при выполнении вставки, попробуйте:

INSERT INTO x_table(instance, user, item) 
    SELECT 919191, 123, 456
        FROM dual
        WHERE NOT EXISTS (SELECT * FROM x_table
                             WHERE user = 123 
                               AND item = 456)

Здесь dual - это таблица только с одной строкой (изначально была найдена в Oracle, а теперь и в других местах). Логика заключается в том, что инструкция SELECT генерирует одну строку данных с необходимыми значениями, но только тогда, когда значения еще не найдены.

Либо посмотрите на оператор MERGE.

ответил Jonathan Leffler 27 Mayam09 2009, 08:31:08
0

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

Запрос будет выглядеть следующим образом:

INSERT IGNORE INTO x_table(instance, user, item) VALUES (919191, 123, 456)

Вы можете добавить уникальный индекс с помощью CREATE UNIQUE INDEX user_item ON x_table (user, item).

ответил MrD 25 AMpWed, 25 Apr 2012 10:52:03 +040052Wednesday 2012, 10:52:03
0

Вы когда-нибудь пробовали что-то подобное?

INSERT INTO x_table
SELECT 919191 as instance, 123 as user, 456 as item
FROM x_table
WHERE (user=123 and item=456)
HAVING COUNT(*) = 0;
ответил temple 16 +04002011-10-16T01:35:16+04:00312011bEurope/MoscowSun, 16 Oct 2011 01:35:16 +0400 2011, 01:35:16
0

С UNIQUE(user, item) сделайте:

Insert into x_table (instance, user, item) values (919191, 123, 456) 
  ON DUPLICATE KEY UPDATE user=123

бит user=123 является «неактивным», чтобы соответствовать синтаксису ON DUPLICATE, фактически ничего не делая при наличии дубликатов.

ответил Alex Martelli 27 Mayam09 2009, 08:37:40
0

Если вы не хотите устанавливать уникальное ограничение, это работает как шарм:

INSERT INTO `table` (`column1`, `column2`) SELECT 'value1', 'value2' FROM `table` WHERE `column1` = 'value1' AND `column2` = 'value2' HAVING COUNT(`column1`) = 0

Надеюсь, это поможет!

ответил Gew 29 PM00000030000004831 2014, 15:23:48
0

Если добавить ограничение на то, что (x_table.user, x_table.item) уникально, вставка другой строки с тем же пользователем и элементом не удастся.

, например:

mysql> create table x_table ( instance integer primary key auto_increment, user integer, item integer, unique (user, item));
Query OK, 0 rows affected (0.00 sec)

mysql> insert into x_table (user, item) values (1,2),(3,4);
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> insert into x_table (user, item) values (1,6);
Query OK, 1 row affected (0.00 sec)

mysql> insert into x_table (user, item) values (1,2);
ERROR 1062 (23000): Duplicate entry '1-2' for key 2
ответил NickZoic 27 Mayam09 2009, 08:00:26
0

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

ответил Beatles1692 27 Mayam09 2009, 08:03:02
0

Вам нужно INSERT INTO table (...) SELECT ... WHERE .... из руководства MySQL 5.6 .

В вашем случае это:

INSERT INTO x_table (instance, user, item) SELECT 919191, 123, 456 
WHERE (SELECT COUNT(*) FROM x_table WHERE user=123 AND item=456) = 0

Или, может быть, поскольку вы не используете сложную логику, чтобы определить, нужно ли запускать INSERT или нет, вы можете просто установить ---- +: = 3 =: + ---- на комбинации этих двух столбцов и затем используйте UNIQUE.

ответил martin 27 MarpmFri, 27 Mar 2015 21:49:13 +03002015-03-27T21:49:13+03:0009 2015, 21:49:13
0
Insert into x_table (instance, user, item) values (919191, 123, 456) 
    where ((select count(*) from x_table where user=123 and item=456) = 0);

Синтаксис может варьироваться в зависимости от вашей БД ...

ответил Rick J 27 Mayam09 2009, 07:56:41
0

Небольшая модификация ответа Алекса, вы также можете просто сослаться на существующее значение столбца:

Insert into x_table (instance, user, item) values (919191, 123, 456) 
  ON DUPLICATE KEY UPDATE user=user
ответил Danny 25 J000000Monday11 2011, 09:50:04
0

Так что это означает PostgreSQL

INSERT INTO x_table
SELECT NewRow.*
FROM (SELECT 919191 as instance, 123 as user, 456 as item) AS NewRow
LEFT JOIN x_table
ON x_table.user = NewRow.user AND x_table.item = NewRow.item
WHERE x_table.instance IS NULL
ответил Danny 25 J000000Monday11 2011, 09:50:04
0

Вы можете использовать следующее решение для решения вашей проблемы:

INSERT INTO x_table(instance, user, item) 
    SELECT 919191, 123, 456
        FROM dual
        WHERE 123 NOT IN (SELECT user FROM x_table)
ответил Keith Becker 16 AM00000010000003631 2018, 01:55:36

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132