Подтвердить что ты не робот

SQL Вставить в таблицу только в том случае, если запись не существует

Я хочу запустить набор запросов для вставки некоторых данных в таблицу SQL, но только если выполняется запись, удовлетворяющая определенным критериям. Таблица имеет 4 поля: id (первичный), fund_id, date и price

У меня есть 3 поля в запросе: fund_id, date и price.

Итак, мой запрос будет выглядеть примерно так:

INSERT INTO funds (fund_id, date, price)
    VALUES (23, '2013-02-12', 22.43)
    WHERE NOT EXISTS (
       SELECT * 
       FROM funds 
       WHERE fund_id = 23
         AND date = '2013-02-12'
    );

Поэтому я хочу только вставить данные, если запись, соответствующая fund_id и date, еще не существует. Если вышесказанное верно, это выглядит довольно неэффективным способом достижения этого, так как каждый раз должен выполняться дополнительный оператор select.

Есть ли лучший способ достижения вышеуказанного?

Изменить: для пояснения ни fund_id, ни date не являются уникальными полями; записи, имеющие один и тот же файл fund_id или date, будут существовать, но ни одна запись не должна иметь как тот же fund_id, ни дату как другой.

4b9b3361

Ответ 1

Хотя ответ, который я изначально обозначил как выбранный, является правильным и достигает того, что я попросил, есть лучший способ сделать это (что другие признали, но не вошли). Составной уникальный индекс должен быть создан в таблице, состоящей из fund_id и date.

ALTER TABLE funds ADD UNIQUE KEY `fund_date` (`fund_id`, `date`);

Затем при вставке записи добавьте условие при возникновении конфликта:

INSERT INTO funds (`fund_id`, `date`, `price`)
    VALUES (23, DATE('2013-02-12'), 22.5)
        ON DUPLICATE KEY UPDATE `price` = `price`; --this keeps the price what it was (no change to the table) or:

INSERT INTO funds (`fund_id`, `date`, `price`)
    VALUES (23, DATE('2013-02-12'), 22.5)
        ON DUPLICATE KEY UPDATE `price` = 22.5; --this updates the price to the new value

Это обеспечит гораздо более высокую производительность подзапроса, а структура таблицы будет выше. Он имеет оговорку, что вы не можете иметь значения NULL в своих уникальных ключевых столбцах, поскольку они по-прежнему рассматриваются как значения MySQL.

Ответ 2

Это может быть простым решением для этого:

INSERT INTO funds (ID, date, price)
SELECT 23, DATE('2013-02-12'), 22.5
  FROM dual
 WHERE NOT EXISTS (SELECT 1 
                     FROM funds 
                    WHERE ID = 23
                      AND date = DATE('2013-02-12'));

p.s. альтернативно (если ID первичный ключ):

 INSERT INTO funds (ID, date, price)
    VALUES (23, DATE('2013-02-12'), 22.5)
        ON DUPLICATE KEY UPDATE ID = 23; -- or whatever you need

см. эту скрипту.

Ответ 3

Предполагая, что вы не можете модифицировать DDL (для создания уникального ограничения) или ограничены только возможностью писать DML, тогда проверьте значение null на результат фильтрации ваших значений по всей таблице

FIDDLE

insert into funds (ID, date, price) 
select 
    T.* 
from 
    (select 23 ID,  '2013-02-12' date,  22.43 price) T  
        left join 
    funds on funds.ID = T.ID and funds.date = T.date
where 
    funds.ID is null