2012-02-04 3 views
0

Я хочу сделать sql-запрос, который будет вставлять значения из одной таблицы в другую таблицу, проверяя, где условие на 1-й таблице.Вставить в ... select from .... query with where condition

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

Существует запрос "insert into select from" pattern в 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) должна существовать только один раз. Храните только один кортеж и удалите другие строки.

+2

Разделите проблему на две части: сначала определите подходящий запрос, который возвращает значения, которые вы хотите, затем используйте этот запрос для вставки значений во вторую таблицу. Похоже, что «вставить в» часть вопроса не имеет значения. –

+0

@ No'am Newman: В sql есть запрос «Вставить в выборку». –

+0

Есть ли дубликаты в 'company_info'? Кроме этого, я не вижу, как этот запрос будет вставлять запись, которая уже существует в 'company_location'. – vhallac

ответ

2

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

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

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

+0

@ Sommath Muluk Он также должен работать, если в compan_info есть дубликаты из-за различий. Надеюсь, я понял тебя правильно. – chris

+0

У меня проблема. Последнее условие должно быть cl1.company_id = ci.company_id. Вот почему он не рассматривал этот кортеж. Теперь он работает нормально. Спасибо за поддержку. Еще один вопрос: мне нужен запрос для удаления дубликатов из company_location. т. е. комбинация (company_id, country_id, city_id) должна существовать только один раз. Сохраняйте только один кортеж и удаляйте другие строки. –

1

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

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

также см. Это: http://stackoverflow.com/questions/2842053/mysql-insert-and-select-order-of-precedence – diEcho

+0

Ссылка не помогла. А также вставляет дубликаты. И вставка значений, хотя кортеж присутствует в таблице. –

2

ВСТАВИТЬ работает Игнорировать регистр.

  • Если вы хотите, чтобы столбец (или столбец) был уникальным, поместите ограничение UNIQUE в таблицу. Если у yu нет UNIQUE CONSTRAINT, поэтому по определению таблица не может содержать нежелательных дубликатов, так как нежелание UNIQUE ограничить дублирование желательно.
  • Добавить UNIQUE (company_id, country_id, CITY_ID) (или, может быть, это ваш первичный ключ для этой таблицы)
  • использование ВСТАВИТЬ ИГНОРИРУЙТЕ

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

SELECT * FROM t1, t2, t3 

Является CROSS JOIN, это означает, что она принимает все возможные комбинации строк из таблицы t1, t2, t3. Обычно WHERE содержит некоторые условия «t1.id = t2.id», чтобы ограничить его и превратить в INNER JOIN, но условия «<>» не выполняются ...

Вам нужен правильный ЛЕВЫЙ ПРИСОЕДИНЯЙТЕСЬ:

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

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

+0

Я не понимаю, извините;) – peufeu

1

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

Решение 1:

Это решение работает только, если у вас есть строка-Id в таблице.

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

@cris: потребовалось одно изменение. Вместо MAX (c1.row_id) MAX (cl1.row_id) Ваше решение работает нормально. Еще раз спасибо. –

Смежные вопросы