2012-03-17 36 views
6

Mam dwie identyczne tabele SQL Server (SOURCE i DESTINATION) z wieloma kolumnami w każdej z nich. Chcę wstawić do tabeli DESTINATION wiersze z tabeli SOURCE, które nie istnieją jeszcze w tabeli DESTINATION. Definiuję równość między dwoma wierszami, jeśli wszystkie kolumny są zgodne, poza znacznikiem czasu, kolumną zliczania i całkowitym kluczem podstawowym. Dlatego chcę wstawić do DESTINATION wszystkie wiersze w SOURCE, które już nie istnieją w DESTINATION ignorowaniu liczby, znacznika czasu i kolumn klucza podstawowego.scalanie zawartości dwóch tabel bez powielania treści

Jak to zrobić?

Dzięki za wszystkie uwagi! Wybrałem polecenie Merge, ponieważ ma strukturę umożliwiającą aktualizację i wstawianie w jednym zestawie, a ja potrzebowałem wykonać aktualizację osobno.

jest to kod, który pracował:

Merge 
into DESTINATION as D 
using SOURCE as S 
on ( 
D.Col1 = S.Col1 
and D.Col2 = S.Col2 
and D.Col3 = S.Col3 
) 
WHEN MATCHED 
THEN UPDATE SET D.Count = S.Count 
WHEN NOT MATCHED THEN 
     INSERT (Col1, Col2, Col3, Count, timestamp) 
     VALUES (S.Col1, S.Col2, S.Col3, S.Count, S.timestamp); 

uwaga: kiedy napisałem pierwszy to pytanie Zadzwoniłem tabele AAA i BBB. I edytowane i zmieniane nazwy AAA do SOURCE I BBB do DESTINATION dla jasności

Odpowiedz

5

użyciu Select oświadczenie na ten cel od SQL Server 2008 jest przestarzała zamiast Select Można użyć Merge oświadczenie:

ref:

http://technet.microsoft.com/en-us/library/bb510625.aspx http://weblogs.sqlteam.com/peterl/archive/2007/09/20/Example-of-MERGE-in-SQL-Server-2008.aspx

+1

Doskonały przypadek użycia dla polecenia MERGE. –

+0

Świetna odpowiedź! Nie wiedziałem o MERGE, ale nadal używam 2005 (przez kilka następnych tygodni), z pewnością będę go używał w przyszłości. – richardtallent

+0

Próbuję dowiedzieć się, jak z niego korzystać. przykład w dokumentacji wymaga przejrzenia elementów w tabeli AAA. Myślę, że używając prawego wyboru należy tego unikać. – Barka

5

coś takiego:

INSERT INTO BBB(id, timestamp, mycount, col1, col2, col3, etc.) 
SELECT id, timestamp, mycount, col1, col2, col3, etc. 
    FROM AAA 
    WHERE 
     NOT EXISTS(SELECT NULL FROM BBB oldb WHERE 
      oldb.col1 = AAA.col1 
      AND oldb.col2 = AAA.col2 
      AND oldb.col3 = AAA.col3 
     ) 

dodać kolumny, ile potrzeba do klauzuli NOT EXISTS.

1

Roztwór stosując dobrą ol'-fashioned LEFT JOIN - uwaga w poniższym przykładzie, tylko pierwszy wiersz BBB jest wstawiony do AAA, ponieważ tylko on nie ma pasującego wiersza w AAA. Zastąpisz kolumny col1 i col2 rzeczywistymi kolumnami tabel.

> select * from AAA; 
+---------------------+------+------+ 
| timestamp   | col1 | col2 | 
+---------------------+------+------+ 
| 2012-03-17 08:17:22 | 1 | 1 | 
| 2012-03-17 08:17:27 | 1 | 2 | 
| 2012-03-17 08:17:30 | 1 | 3 | 
| 2012-03-17 08:17:32 | 1 | 4 | 
| 2012-03-17 08:17:49 | 2 | 2 | 
| 2012-03-17 08:17:52 | 2 | 3 | 
| 2012-03-17 08:17:54 | 2 | 4 | 
+---------------------+------+------+ 
7 rows in set (0.00 sec) 

> select * from BBB; 
+---------------------+------+------+ 
| timestamp   | col1 | col2 | 
+---------------------+------+------+ 
| 2012-03-17 08:18:16 | 2 | 1 | 
| 2012-03-17 08:18:18 | 2 | 2 | 
| 2012-03-17 08:18:20 | 2 | 3 | 
+---------------------+------+------+ 
3 rows in set (0.00 sec) 

> INSERT INTO AAA 
    SELECT BBB.* FROM BBB 
    LEFT JOIN AAA 
    USING(col1,col2) 
    WHERE AAA.timestamp IS NULL; 

> select * from AAA; 
+---------------------+------+------+ 
| timestamp   | col1 | col2 | 
+---------------------+------+------+ 
| 2012-03-17 08:17:22 | 1 | 1 | 
| 2012-03-17 08:17:27 | 1 | 2 | 
| 2012-03-17 08:17:30 | 1 | 3 | 
| 2012-03-17 08:17:32 | 1 | 4 | 
| 2012-03-17 08:17:49 | 2 | 2 | 
| 2012-03-17 08:17:52 | 2 | 3 | 
| 2012-03-17 08:17:54 | 2 | 4 | 
| 2012-03-17 08:18:16 | 2 | 1 | 
+---------------------+------+------+ 
8 rows in set (0.00 sec) 
+0

USING() nie jest obsługiwany w MSSQL. IIRC, to funkcja MySQL. Ale podoba mi się twoja metoda łączenia, składnia jest mniej szczegółowa, ale czystsza niż skorelowane podkwerendy. – richardtallent

+0

@ richardtallent można użyć ON() zamiast USING() w MSSQL? – gcbenison