Переместить данные SQL из одной таблицы в другую - PullRequest
58 голосов
/ 23 октября 2009

Мне было интересно, можно ли переместить все строки данных из одной таблицы в другую, которые соответствуют определенному запросу?

Например, мне нужно переместить все строки таблицы из Таблицы1 в Таблицу2, где их имя пользователя = 'X' и пароль = 'X', чтобы они больше не появлялись в Таблице 1.

Я использую SQL Server 2008 Management Studio.

Ответы [ 12 ]

101 голосов
/ 23 октября 2009

Должно быть возможно с использованием двух операторов в одной транзакции, вставки и удаления:

INSERT INTO Table2 (<columns>)
SELECT <columns>
FROM Table1
WHERE <condition>;

DELETE FROM Table1
WHERE <condition>;

COMMIT;

Это самая простая форма. Если вам нужно беспокоиться о вставке новых совпадающих записей в table1 между двумя операторами, вы можете добавить and exists <in table2>.

40 голосов
/ 27 февраля 2014

Это древний пост, извините, но я только натолкнулся на него сейчас, и я хотел дать свое решение тому, кто может наткнуться на этот один день.

Как уже упоминалось, выполнение INSERT, а затем DELETE может привести к проблемам с целостностью, поэтому, возможно, способ обойти это и выполнить все аккуратно в одном утверждении - это воспользоваться [deleted] временная таблица.

DELETE FROM [source]
OUTPUT [deleted].<column_list>
INTO [destination] (<column_list>)
18 голосов
/ 21 марта 2011

Все эти ответы запускают один и тот же запрос для INSERT и DELETE. Как упоминалось ранее, это рискует, когда DELETE забирает записи, вставленные между операторами, и может быть медленным, если запрос сложный (хотя умные механизмы «должны» быстро выполнить второй вызов).

Правильный способ (при условии, что INSERT находится в новой таблице) - это УДАЛИТЬ против table1, используя ключевое поле table2.

Удаление должно быть:

DELETE FROM tbl_OldTableName WHERE id in (SELECT id FROM tbl_NewTableName)

Извините за мой синтаксис, я прыгаю между движками, но вы поняли.

8 голосов
/ 23 октября 2009

Да, это так. Сначала INSERT + SELECT, а затем DELETE orginals.

INSERT INTO Table2 (UserName,Password)
SELECT UserName,Password FROM Table1 WHERE UserName='X' AND Password='X'

затем удалите оригиналы

DELETE FROM Table1 WHERE UserName='X' AND Password='X'

вы можете сохранить UserID или какой-либо другой первичный ключ, затем вы можете использовать IDENTITY INSERT для сохранения ключа.

см. Больше на SET IDENTITY_INSERT на MSDN

3 голосов
/ 23 октября 2009

Вы должны быть в состоянии с подзапросом в инструкции INSERT.

INSERT INTO table1(column1, column2) SELECT column1, column2 FROM table2 WHERE ...;

с последующим удалением из таблицы 1.

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

3 голосов
/ 23 октября 2009

Попробуйте это

INSERT INTO TABLE2 (Cols...) SELECT Cols... FROM TABLE1 WHERE Criteria

Тогда

DELETE FROM TABLE1 WHERE Criteria
2 голосов
/ 23 октября 2009

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

SELECT * INTO tbl_NewTableName 
FROM tbl_OldTableName
WHERE Condition1=@Condition1Value

Затем выполните простое удаление:

DELETE FROM tbl_OldTableName
WHERE Condition1=@Condition1Value
1 голос
/ 20 июня 2018

Более точное представление о том, на что намекают некоторые другие ответы:

DELETE sourceTable
OUTPUT DELETED.*
INTO destTable (Comma, separated, list, of, columns)
WHERE <conditions (if any)>
1 голос
/ 13 сентября 2017

Используйте этот единственный SQL-оператор, который не требует фиксации / отката с несколькими операторами.

INSERT Table2 (
      username,password
) SELECT username,password
      FROM    (
           DELETE Table1
           OUTPUT
                   DELETED.username,
                   DELETED.password
           WHERE username = 'X' and password = 'X'
      ) AS RowsToMove ;

Работает на сервере SQL, внести соответствующие изменения для MySql

1 голос
/ 24 сентября 2016

Вот как это сделать с одним утверждением

WITH deleted_rows AS (
DELETE FROM source_table WHERE id = 1
RETURNING *
) 
INSERT INTO destination_table 
SELECT * FROM deleted_rows;

Пример:

    postgres=# select * from test1 ;
 id |  name
----+--------
  1 | yogesh
  2 | Raunak
  3 | Varun
(3 rows)


postgres=# select * from test2;
 id | name
----+------
(0 rows)


postgres=# WITH deleted_rows AS (
postgres(# DELETE FROM test1 WHERE id = 1
postgres(# RETURNING *
postgres(# )
postgres-# INSERT INTO test2
postgres-# SELECT * FROM deleted_rows;
INSERT 0 1


postgres=# select * from test2;
 id |  name
----+--------
  1 | yogesh
(1 row)

postgres=# select * from test1;
 id |  name
----+--------
  2 | Raunak
  3 | Varun
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...