Вставить в ... выберите из .... запрос с условием где - PullRequest
0 голосов
/ 04 февраля 2012

Я хочу сделать SQL-запрос, который будет вставлять значения из одной таблицы в другую, проверяя, где условие на 1-й таблице.

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

В sql есть запрос "вставить в шаблон выбора".

Я пробовал следующий запрос. Но он вставляет много дубликатов.

INSERT INTO 
    company_location (company_id, country_id, city_id)
SELECT 
    ci.company_id, hq_location, hq_city
FROM 
    company_info ci, company_location cl 
WHERE  
    ci.company_id <> cl.company_id
    AND cl.country_id <> ci.hq_location
    AND cl.city_id <> ci.hq_city;

Избегание дублирования означает, что кортеж (company_id, country_id, city_id) не должен добавляться снова. И я должен добавить еще 4 таблицы в эти таблицы.

Также мне требуется запрос на удаление дубликатов из company_location. то есть комбинация (company_id, country_id, city_id) должна существовать только один раз. Оставьте только один кортеж и удалите другие строки.

Ответы [ 4 ]

2 голосов
/ 04 февраля 2012

INSERT INGORE работает.

  • Если вы хотите, чтобы столбец (или набор столбцов) был уникальным, наложите уникальное ограничение на вашу таблицу.Если у вас нет UNIQUE CONSTRAINT, поэтому, по определению, таблица не может содержать нежелательных дубликатов, поскольку отсутствие ограничения UNIQUE означает, что дубликаты желательны.
  • Добавьте UNIQUE (company_id, country_id, city_id) (или, может быть, этоваш первичный ключ для этой таблицы)
  • используйте INSERT IGNORE

Вы также можете правильно переписать свой запрос.Запрос не выполняет то, что вы думаете, и вы не можете делать то, что хотите, используя старый синтаксис соединения 18-го века.

SELECT * FROM t1, t2, t3

Является ли CROSS JOIN, это означает, что он принимает все возможные комбинациистрок из таблицы t1, t2, t3.Обычно WHERE содержит некоторые условия "t1.id = t2.id", чтобы ограничить его и превратить его во ВНУТРЕННЕЕ СОЕДИНЕНИЕ, но условия "<>" этого не делают ...

Вам необходим правильный ЛЕВПРИСОЕДИНЯЙТЕСЬ:

INSERT INTO company_location (company_id,country_id,city_id)
SELECT ci.company_id, hq_location, hq_city
FROM company_info ci,
LEFT JOIN  company_location cl ON (
  ci.company_id = cl.company_id
  AND cl.country_id = ci.hq_location
  AND cl.city_id = ci.hq_city
)
WHERE cl.company_id IS NULL
2 голосов
/ 04 февраля 2012

Надеюсь, этот непроверенный скрипт поможет!Он вставляет каждую комбинацию только один раз.

INSERT INTO company_location 
    (company_id,country_id,city_id)
SELECT  distinct ci.company_id, 
        ci.hq_location, 
        ci.hq_city
FROM    company_info ci  
WHERE  ci.company_id NOT IN 
        (SELECT cl1.company_id FROM company_location cl1
            WHERE cl1.country_id = ci.hq_location
            AND cl1.city_id = ci.hq_city
            AND cl1.company_id = ci.company_id)
1 голос
/ 04 февраля 2012

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

Решение 1:

Это решение работает, только если в таблице есть идентификатор строки.

    DELETE FROM company_location
WHERE id NOT IN
    (SELECT     MAX(cl1.id)
    FROM company_location cl1
        WHERE   cl1.company_id = company_location.company_id
        AND     cl1.country_id = company_location.country_id
        AND     cl1.city_id = company_location.city_id)

Решение 2:

Это работает без row_id.Он записывает все данные во временную таблицу.Удаляет содержимое первой таблицы.И вставляет каждый пучок только один раз.К этому решению: будьте осторожны, если вы определили ограничения для этой таблицы!

CREATE TEMPORARY TABLE tmp_company_location
(
    company_id bigint
    ,country_id bigint
    ,city_id bigint
);

INSERT INTO tmp_company_location
(company_id,country_id,city_id)
SELECT DISTINCT
    company_id
    ,country_id
    ,city_id 
FROM company_location WHERE 1;

DELETE FROM company_location;

INSERT INTO company_location
SELECT DISTINCT
    company_id
    ,country_id
    ,city_id 
FROM tmp_company_location;
1 голос
/ 04 февраля 2012

использование INSERT IGNORE INTO
от Mysql Docs

   Specify IGNORE to ignore rows that would cause duplicate-key violations. 
...